我在绝对定位的div中的onmouseout函数遇到了麻烦。当鼠标击中div中的子元素时,mouseout事件发生,但我不希望它发生,直到鼠标离开父元素,绝对div。

我如何防止mouseout事件从发射时,它击中一个子元素没有jquery。

我知道这与事件冒泡有关,但我没有找到如何解决这个问题的方法。

我在这里找到了一个类似的帖子:如何禁用由子元素触发的鼠标退出事件?

但是,该解决方案使用jQuery。


当前回答

如果你添加(或拥有)一个CSS类或id到父元素,那么你可以这样做:

<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
  }
}

所以只有当事件在父div上时,才会执行东西。

其他回答

下面是一个基于下面内容的更优雅的解决方案。 它解释了从一个以上层次的孩子中冒出来的事件。 它还考虑了跨浏览器的问题。

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);
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
});

使用onmouseleave。

或者,在jQuery中使用mouseleave()

这正是你要找的东西。例子:

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

或者,在jQuery中:

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

这里有一个例子。

香草也可以用这种方法

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>

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);

我做了一个快速的JsFiddle演示,所有的CSS和HTML需要,检查它…

编辑固定链接跨浏览器支持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;
}

和一个新的JSFiddle, EDIT更新链接