199

onmouseout絶対位置の div で関数に問題があります。マウスがdivの子要素に当たると、mouseoutイベントが発生しますが、マウスが親の絶対divから出るまで発生させたくありません。

mouseoutjqueryなしで子要素にヒットしたときにイベントが発生しないようにするにはどうすればよいですか。

これはイベントのバブリングと関係があることは知っていますが、これを解決する方法を見つけることができません。

ここで同様の投稿を見つけました:子要素によってトリガーされたマウスアウト イベントを無効にするには?

ただし、そのソリューションは jQuery を使用します。

4

22 に答える 22

156

を使用しonmouseleaveます。

または、jQuery では、mouseleave()

それはまさにあなたが探しているものです。例:

<div class="outer" onmouseleave="yourFunction()">
    <div class="inner">
    </div>
</div>

または、jQuery の場合:

$(".outer").mouseleave(function(){
    //your code here
});

例はこちらです。

于 2015-06-07T18:37:00.327 に答える
119

ほとんどの場合に機能する単純な純粋な CSS ソリューションpointer-eventsの場合、子を次のように設定して削除できます。none

.parent * {
     pointer-events: none;
}

ブラウザのサポート: IE11+

于 2013-09-16T20:45:40.177 に答える
99
function onMouseOut(event) {
        //this is the original element the event handler was assigned to
        var e = event.toElement || event.relatedTarget;
        if (e.parentNode == this || e == this) {
           return;
        }
    alert('MouseOut');
    // handle mouse event here!
}



document.getElementById('parent').addEventListener('mouseout',onMouseOut,true);

必要なすべての CSS と HTML を使用して、簡単な JsFiddle デモを作成しました。チェックしてください...

クロスブラウザサポートの固定リンクを編集http://jsfiddle.net/RH3tA/9/

これは直接の親のみをチェックすることに注意してください。親 div に子がネストされている場合は、「元の要素」を探して要素の親を何らかの方法でトラバースする必要があります。

ネストされた子の編集例

編集できればクロスブラウザ用に修正

function makeMouseOutFn(elem){
    var list = traverseChildren(elem);
    return function onMouseOut(event) {
        var e = event.toElement || event.relatedTarget;
        if (!!~list.indexOf(e)) {
            return;
        }
        alert('MouseOut');
        // handle mouse event here!
    };
}

//using closure to cache all child elements
var parent = document.getElementById("parent");
parent.addEventListener('mouseout',makeMouseOutFn(parent),true);

//quick and dirty DFS children traversal, 
function traverseChildren(elem){
    var children = [];
    var q = [];
    q.push(elem);
    while (q.length > 0) {
      var elem = q.pop();
      children.push(elem);
      pushAll(elem.children);
    }
    function pushAll(elemArray){
      for(var i=0; i < elemArray.length; i++) {
        q.push(elemArray[i]);
      }
    }
    return children;
}

そして、新しいJSFiddleEDIT更新されたリンク

于 2011-01-15T05:47:35.227 に答える
28

以下は、以下に基づいたよりエレガントなソリューションです。複数のレベルの子から発生するイベントを説明します。また、クロスブラウザーの問題も考慮されています。

function onMouseOut(this, event) {
//this is the original element the event handler was assigned to
   var e = event.toElement || event.relatedTarget;

//check for all children levels (checking from bottom up)
while(e && e.parentNode && e.parentNode != window) {
    if (e.parentNode == this||  e == this) {
        if(e.preventDefault) e.preventDefault();
        return false;
    }
    e = e.parentNode;
}

//Do something u need here
}

document.getElementById('parent').addEventListener('mouseout',onMouseOut,true);
于 2012-10-30T14:24:46.267 に答える
14

jQuery を使用している場合は、「mouseleave」関数を使用することもできます。これは、これらすべてを処理します。

$('#thetargetdiv').mouseenter(do_something);
$('#thetargetdiv').mouseleave(do_something_else);

do_something は、マウスが targetdiv またはその子のいずれかに入ったときに起動し、do_something_else は、マウスが targetdiv およびその子のいずれかを離れたときにのみ起動します。

于 2014-05-06T23:33:50.317 に答える
13

私にインスピレーションを与えてくれた Amjad Masad に感謝します。

私はIE9、FF、およびChromeで動作するように見える次のソリューションを持っています。コードは非常に短いです(複雑なクロージャーと横方向の子要素なし):

    DIV.onmouseout=function(e){
        // check and loop relatedTarget.parentNode
        // ignore event triggered mouse overing any child element or leaving itself
        var obj=e.relatedTarget;
        while(obj!=null){
            if(obj==this){
                return;
            }
            obj=obj.parentNode;
        }
        // now perform the actual action you want to do only when mouse is leaving the DIV
    }
于 2012-06-02T04:40:48.117 に答える
7

Quirksmodeには必要なすべての答えがあると思います (さまざまなブラウザーのバブリング動作とmouseenter /mouseleaveイベント)。しかし、そのイベント バブリングの混乱に対する最も一般的な結論、JQuery や Mootools などのフレームワーク ( mouseenterとこれはまさにあなたが直観したとおりのイベントです)

必要に応じて自分で行うか
イベント部分 (およびその依存関係) だけを使用して Mootools のカスタムの「無駄のない」バージョンを作成できます

于 2011-01-15T03:34:08.093 に答える
5

私は非常に簡単な解決策を見つけました、

onmousout="myfunc()" イベントよりも onmouseleave="myfunc()" イベントを使用するだけです

私のコードではうまくいきました!!

例:

<html>
<head>
<script type="text/javascript">
   function myFunc(){
      document.getElementById('hide_div').style.display = 'none';
   }
   function ShowFunc(){
      document.getElementById('hide_div').style.display = 'block';
   }
</script>
</head>
<body>
<div onmouseleave="myFunc()" style='border:double;width:50%;height:50%;position:absolute;top:25%;left:25%;'>
   Hover mouse here
   <div id='child_div' style='border:solid;width:25%;height:25%;position:absolute;top:10%;left:10%;'>
      CHILD <br/> It doesn't fires if you hover mouse over this child_div
   </div>
</div>
<div id="hide_div" >TEXT</div>
<a href='#' onclick="ShowFunc()">Show "TEXT"</a>
</body>
</html>

mouseout 関数を使用した同じ例:

<html>
<head>
<script type="text/javascript">
   function myFunc(){
      document.getElementById('hide_div').style.display = 'none';
   }
   function ShowFunc(){
      document.getElementById('hide_div').style.display = 'block';
   }
</script>
</head>
<body>
<div onmouseout="myFunc()" style='border:double;width:50%;height:50%;position:absolute;top:25%;left:25%;'>
   Hover mouse here
   <div id='child_div' style='border:solid;width:25%;height:25%;position:absolute;top:10%;left:10%;'>
      CHILD <br/> It fires if you hover mouse over this child_div
   </div>
</div>
<div id="hide_div">TEXT</div>
<a href='#' onclick="ShowFunc()">Show "TEXT"</a>
</body>
</html>

それが役に立てば幸い :)

于 2012-12-26T13:03:59.840 に答える
2

これを処理する方法は2つあります。

1)コールバックのevent.targetの結果をチェックして、親のdivと一致するかどうかを確認します

var g_ParentDiv;

function OnMouseOut(event) {
    if (event.target != g_ParentDiv) {
        return;
    }
    // handle mouse event here!
};


window.onload = function() {
    g_ParentDiv = document.getElementById("parentdiv");
    g_ParentDiv.onmouseout = OnMouseOut;
};

<div id="parentdiv">
    <img src="childimage.jpg" id="childimg" />
</div>

2)または、イベントキャプチャを使用して、コールバック関数でevent.stopPropagationを呼び出します。

var g_ParentDiv;

function OnMouseOut(event) {

    event.stopPropagation(); // don't let the event recurse into children

    // handle mouse event here!
};


window.onload = function() {
    g_ParentDiv = document.getElementById("parentdiv");
    g_ParentDiv.addEventListener("mouseout", OnMouseOut, true); // pass true to enable event capturing so parent gets event callback before children
};

<div id="parentdiv">
    <img src="childimage.jpg" id="childimg" />
</div>
于 2011-01-15T04:10:24.087 に答える
1

私はこれを魅力的に機能させます:

function HideLayer(theEvent){
 var MyDiv=document.getElementById('MyDiv');
 if(MyDiv==(!theEvent?window.event:theEvent.target)){
  MyDiv.style.display='none';
 }
}

ああ、MyDivタグは次のようになります。

<div id="MyDiv" onmouseout="JavaScript: HideLayer(event);">
 <!-- Here whatever divs, inputs, links, images, anything you want... -->
<div>

このように、onmouseout が子、孫などに渡された場合、style.display='none'実行されません。しかし、onmouseout が MyDiv の外に出ると実行されます。

したがって、伝播を停止したり、タイマーを使用したりする必要はありません...

例をありがとう、私はそれらからこのコードを作ることができました。

これが誰かに役立つことを願っています。

次のように改善することもできます。

function HideLayer(theLayer,theEvent){
 if(theLayer==(!theEvent?window.event:theEvent.target)){
  theLayer.style.display='none';
 }
}

そして、次のような DIV タグ:

<div onmouseout="JavaScript: HideLayer(this,event);">
 <!-- Here whatever divs, inputs, links, images, anything you want... -->
<div>

より一般的には、1 つの div だけでなくid="..."、各レイヤーに追加する必要もありません。

于 2012-03-28T11:17:25.043 に答える
0

元の要素のオフセットをチェックして要素の境界のページ座標を取得し、マウスアウトがそれらの境界の外にある場合にのみマウスアウト アクションがトリガーされるようにします。汚れていますが、機能します。

$(el).live('mouseout', function(event){
    while(checkPosition(this, event)){
        console.log("mouseovering including children")
    }
    console.log("moused out of the whole")
})

var checkPosition = function(el, event){
    var position = $(el).offset()
    var height = $(el).height()
    var width = $(el).width()
    if (event.pageY > position.top 
|| event.pageY < (position.top + height) 
|| event.pageX > position.left 
|| event.pageX < (position.left + width)){
    return true
}
}
于 2012-01-25T15:08:46.240 に答える
0

If you added (or have) a CSS class or id to the parent element, then you can do something like this:

<div id="parent">
  <div>
  </div>
</div>

JavaScript:
document.getElementById("parent").onmouseout = function(e) {
  e = e ? e : window.event //For IE
  if(e.target.id == "parent") {
    //Do your stuff
  }
}

So stuff only gets executed when the event is on the parent div.

于 2013-09-13T19:19:09.933 に答える
0
var elem = $('#some-id');
elem.mouseover(function () {
   // Some code here
}).mouseout(function (event) {
   var e = event.toElement || event.relatedTarget;
   if (elem.has(e).length > 0) return;

   // Some code here
});
于 2012-10-02T15:49:06.020 に答える
0

また、vanillajsの場合、そのように使用できます

document.querySelector('.product_items') && document.querySelector('.product_items').addEventListener('mouseleave', () => updateCart())


const updateCart = () => {
let total = 0;
document.querySelectorAll('input') && document.querySelectorAll('input').forEach(item => total += +item.value)
  document.getElementById('total').innerHTML = total
}
<div class="product_items">
  <div class="product_item">
    <div class="product_name">
    </div>
    <div class="multiply__btn">
      <button type="button">-</button>
      <input name="test" type="text">
      <button type="button">+</button>
    </div>
  </div>
  <div class="product_item">
    <div class="product_name">
    </div>
    <div class="multiply__btn">
      <button type="button">-</button>
      <input name="test" type="text">
      <button type="button">+</button>
    </div>
  </div>
  <div class="product_item">
    <div class="product_name">
    </div>
    <div class="multiply__btn">
      <button type="button">-</button>
      <input name="test" type="text">
      <button type="button">+</button>
    </div>
  </div>
</div>

<div id="total"></div>

于 2021-07-16T09:27:20.767 に答える