当悬停父绝对div的子元素而没有jQuery时,防止onmouseout

Joh*_*ohn 149 javascript css onmouseout dom-events

onmouseout在绝对positoned div 中遇到了这个函数的问题.当鼠标命中div中的子元素时,mouseout事件会触发,但我不希望它触发,直到鼠标超出父,绝对div.

如何mouseout在遇到没有jquery的子元素时阻止事件触发.

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

我在这里找到了类似的帖子:如何禁用子元素触发的mouseout事件?

但是该解决方案使用jQuery.

小智 101

使用onmouseleave.

或者,在jQuery中,使用 mouseleave()

这是你正在寻找的确切的事情.例:

<div class="outer" onmouseleave="yourFunction()">
    <div class="inner">
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

或者,在jQuery中:

$(".outer").mouseleave(function(){
    //your code here
});
Run Code Online (Sandbox Code Playgroud)

一个例子就在这里.

  • 这应该被接受为最好的答案imho. (7认同)
  • `onMouseLeave`也是我最终使用的,因为它没有冒出来. (3认同)
  • 这个答案比手动检查父母更有力 (3认同)

Amj*_*sad 92

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);
Run Code Online (Sandbox Code Playgroud)

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

用于跨浏览器支持的EDIT FIXED链接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;
}
Run Code Online (Sandbox Code Playgroud)

还有一个新的JSFiddle,EDIT更新链接

  • 这不起作用.`mouseleave`是正确的答案 (15认同)
  • 如果你有大孩子怎么办?还是伟大的孩子?即你有一个递归的解决方案,而不仅仅是移民儿童吗? (2认同)

Zac*_*ier 86

对于在某些情况下(IE11或更新版本)工作的更简单的纯CSS解决方案,可以通过将子pointer-events设置为none

.parent * {
     pointer-events: none;
}
Run Code Online (Sandbox Code Playgroud)

  • 这可以防止鼠标输出,但对我来说,它还可以防止实际的孩子被点击作为菜单中的选择. (8认同)
  • 辉煌!完全解决了我的问题! (3认同)
  • 这应该是第一个或至少是第二个答案,我已经准备好了解事件监听器的麻烦,这也完全解决了我的问题.很简单 ! (3认同)
  • 仅当您在该区域内没有其他控制器元素(编辑、删除)时它才有效,因为此解决方案也会阻止它们。 (2认同)

Sam*_*lie 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);
Run Code Online (Sandbox Code Playgroud)


Law*_*Mok 14

感谢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
    }
Run Code Online (Sandbox Code Playgroud)


Jam*_*own 12

如果你正在使用jQuery,你也可以使用"mouseleave"功能,它可以为你处理所有这些.

$('#thetargetdiv').mouseenter(do_something);
$('#thetargetdiv').mouseleave(do_something_else);
Run Code Online (Sandbox Code Playgroud)

当鼠标进入thetargetdiv或其任何子节点时,do_something将触发,do_something_else将仅在鼠标离开targetgetdiv及其任何子节点时触发.


小智 7

尝试 mouseleave()

示例:

<div id="parent" mouseleave="function">
   <div id="child">

   </div>
</div>
Run Code Online (Sandbox Code Playgroud)

;)


kav*_*avi 7

而不是onmouseout使用onmouseleave。

您尚未向我们展示您的特定代码,因此我无法在您的特定示例中向您展示如何执行此操作。

但这很简单:只需将onmouseout替换为onmouseleave。

就是这么简单:)

如果不确定如何做,请参阅以下说明:

https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onmousemove_leave_out

蛋糕的和平:)享受它:)


Rub*_*ben 6

我认为Quirksmode有你需要的所有答案(不同的浏览器冒泡行为和mouseenter/mouseleave事件),但我认为这个事件冒泡混乱最常见的结论使用像JQuery或Mootools这样的框架(它具有mouseentermouseleave事件,这正是你直觉会发生的事情).

看看他们是如何做到的,如果你愿意,可以自己动手,
或者你可以只用事件部分(及其依赖项)创建 Mootools的自定义 "精益平均"版本.


小智 5

我找到了一个非常简单的解决方案,

只使用onmouseleave ="myfunc()"事件而不是onmousout ="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>
Run Code Online (Sandbox Code Playgroud)

与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>
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你 :)