子要素によってトリガーされるマウスアウトイベントを無効にする方法は?


107

問題を詳しく説明しましょう:

要素の上にカーソルを置いたときに絶対位置のdivを表示したい。これはjQueryを使用すると非常に簡単で、問題なく動作します。ただし、マウスがいずれかの子要素の上に移動すると、含まれているdivのmouseoutイベントがトリガーされます。子要素にカーソルを合わせたときに、JavaScriptが含まれている要素のマウスアウトイベントをトリガーしないようにするにはどうすればよいですか。

jQueryでそれを行うための最良かつ最短の方法は何ですか?

ここに私が何を意味するのかを説明するための簡単な例があります:

HTML:

<a>Hover Me</a>
<div>
  <input>Test</input>
  <select>
    <option>Option 1</option>
    <option>Option 2</option>
  </select>
</div>

JavaScript / jQuery:

$('a').hover( function() { $(this).next().show() }
              function() { $(this).next().hide() } );

回答:


209

質問は少し古いですが、先日この問題に遭遇しました。

jQueryの最近のバージョンでこれを行う最も簡単な方法は、使用することですmouseentermouseleaveするのではなく、イベントをmouseoverしてmouseout

次のようにして、動作をすばやくテストできます。

$(".myClass").on( {
   'mouseenter':function() { console.log("enter"); },
   'mouseleave':function() { console.log("leave"); }
});

4
jquery以外のJavaScript関連の問題を解決しました。イベントリスナーでmouseleaveではなくmouseenter / mouseoutを使用していました。
ジョーE.

1
検索のために、これらのマウスイベント動作はAS3 ROLL_OVERと同等ROLL_OUTです。
ジェフワード

2
私はいくつかの頭痛を救った。子要素をホバリングmouseoutすると、実際にはまだ親要素内にあるのに、親のイベントがトリガーされるのは奇妙です。
javiniar.leonard

18

簡単にするために、マウスオーバーイベントがバインドされている要素内に新しく表示されたコンテンツを配置するために、HTMLを少し再編成します。

<div id="hoverable">
  <a>Hover Me</a>
  <div style="display:none;">
    <input>Test</input>
    <select>
      <option>Option 1</option>
      <option>Option 2</option>
    </select>
  </div>
</div>

次に、次のようなことをすることができます:

$('#hoverable').hover( function() { $(this).find("div").show(); },
                       function() { $(this).find("div").hide(); } );

注:インラインcssはお勧めしませんが、例を簡単に消化できるようにするために行われました。


これは確かに非常にシンプルでクリーンなソリューションです。思い出させてくれてありがとう。しかし、質問とは完全に異なる私の特定の状況では、これはオプションです。ありがとう!
Sander Versluys、2008

ここで他の人が説明しているさまざまな方法を試した後、私はあなたの方法に戻り、私の場合にはそれを機能させました。わーい!:-)
Sander Versluys 2008

11

うん、みんな、.mouseleave代わりに使用して.mouseoutください:

$('div.sort-selector').mouseleave(function() {
    $(this).hide();
});

または、以下と組み合わせて使用​​することもできますlive

$('div.sort-selector').live('mouseleave', function() {
    $(this).hide();
});

8

あなたは、javascriptの防止イベントバブリングに相当するjQueryを探しています。

これをチェックしてください:

http://docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29

基本的には、子DOMノードでイベントをキャッチする必要があり、そこでDOMツリーへの伝播が停止します。別の方法は、実際には推奨されていませんが(ページ上の既存のイベントを大幅に混乱させる可能性があるため)、イベントキャプチャーをページ上の特定の要素に設定し、すべてのイベントを受信します。これはDnDの振る舞いなどには役立ちますが、あなたの場合には絶対に役に立ちません。



3

マウス座標がmouseoutイベントの要素の外側にあるかどうかを確認しています。

それは機能しますが、そのような単純なもののためのコードの多くです:(

function mouseOut(e)
{
    var pos = GetMousePositionInElement(e, element);
    if (pos.x < 0 || pos.x >= element.size.X || pos.y < 0 || pos.y >= element.size.Y)
    {
        RealMouseOut();
    }
    else
    {
         //Hit a child-element
    }
}

コードは読みやすくするために削減されており、そのままでは機能しません。


1

私はライアンに同意します。

あなたの問題は、「次の」divがAの「子」ではないことです。HTMLまたはjQueryが「a」要素がDOMの子divに関連していることを知る方法はありません。それらをラップしてラッパーにホバーを置くと、それらが関連付けられます。

ただし、彼のコードはベストプラクティスに沿っていないことに注意してください。要素に非表示のスタイルをインラインで設定しないでください。ユーザーがCSSを持っているがJavaScriptを持っていない場合、要素は非表示になり、表示できなくなります。その宣言をdocument.readyイベントに入れることをお勧めします。


document.readyイベントに非表示を設定することに完全に同意します。インラインcssは、完全に機能する例をできるだけ簡単な方法で伝えるためのものです。わかりやすくするために返信を編集します。
Ryan McGeary、

1

pointer-events: none;は私の子要素CSSを追加することでこの問題を解決しました


これは、マウスオーバーイベントとマウスリーブイベントを使用して独自のポップオーバーを構築するレガシーコードを修正する際に非常に役立ちました
CM

0

これが通常処理されるのを私が目にした方法は、HoverMe要素からマウスを移動する間に約1/2秒の遅延があることです。マウスをホバーされた要素に移動するとき、要素の上にホバーしていることを示す変数を設定し、この変数が設定されている場合、ホバーされた部分が非表示にならないようにします。次に、ホバーされた要素から同様の非表示関数OnMouseOutを追加して、マウスを離したときに要素を非表示にする必要があります。申し訳ありませんが、コードや具体的なものをお伝えすることはできませんが、これが正しい方向を示していることを願っています。


はいiddそのようなソリューションを実装しました。これは本当によくある問題です。他にどんな解決策があるのか​​本当に気になります...回答ありがとうございます!
Sander Versluys、2008

0

古い質問ですが、陳腐化することはありません。正しい答えは、bytebriteによって与えられたものでなければなりません。

mouseover / mouseoutとmouseenter / mouseleaveの違いを指摘しておきます。あなたはここで素晴らしくて役に立つ説明を読むことができます(動作するデモについてはページの一番下に行きます)。を使用するmouseoutと、子要素であっても、マウスが別の要素に入るとイベントが停止します。一方、を使用するmouseleave場合、マウスが子要素の上にあるときにイベントはトリガーされません。これは、OPが達成したい動作です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.