为li标记重复onmouseover / onmouseout调用

Duplicate onmouseover / onmouseout calls for the li tag

本文关键字:onmouseover onmouseout 调用 li      更新时间:2023-09-26

我有以下代码。(您可以将其复制到一个文件中以便在Firefox中进行调试,并在Firebug的Console选项卡中查看输出)。

当我将onmouseover事件添加到li标签,并将鼠标移动到li区域时,控制台信息出现。

问题是当我移动鼠标从图像(谷歌标志)到它下面的文本,多个信息打印出来。为什么触发了onmouseout事件,因为我没有离开li区域?

在这种情况下,我应该做些什么来防止触发onmouseout事件。

谢谢! !

<html>
<body>
<div>
    <ul>
        <li onmouseover="console.info('over')" onmouseout="console.info('out')" style="float:left;display:block;width:30%;height:200px;border: 2px solid red;">
            <img src="https://www.google.com/intl/en_com/images/srpr/logo3w.png">
            <br/>
            <br/>
            <a href="#">Google</a>
        </li>
        <li style="float:left;display:block;width:30%;">
            <img src="https://www.google.com/intl/en_com/images/srpr/logo3w.png">
            <br/>
            <br/>
            <a href="#">Google</a>
        </li>
        <li style="float:left;display:block;width:30%;">
            <img src="https://www.google.com/intl/en_com/images/srpr/logo3w.png">
            <br/>
            <br/>
            <a href="#">Google</a>
        </li>
    </ul>
</div>
</body>
</html>

Events 冒泡上DOM树。因此,当光标离开img元素时,将生成一个mouseout事件,并触发绑定到父li元素的事件处理程序。

两种方法可以处理这种情况:

防止事件冒泡

如果你想防止事件冒泡,你可以为事件产生的元素分配一个事件处理程序,并调用event对象的stopPropagation方法(或IE中的cancelBubble属性):

function handler(event) {
    event = event || window.event; // IE
    if(event.stopPropagation) {
        event.stopPropagation();   // W3C
    }
    else {
        event.cancelBubble = true; // IE
    }
}

问题是您必须将此处理程序绑定到每个子元素,这不是很方便。因此,下面的方法更容易实现。

测试事件发生的位置

您可以通过event.target(或IE中的event.srcElement)获得事件起源元素的引用。绑定到li元素的事件处理程序应该如下所示:

function handler(event) {
    event = event || window.event; // IE
    var target = event.target || event.srcElement; // IE
    if(target === this) {   // event originated where the handler was bound to
        console.info('out');
    }
}
并以 命名
onmouseout="handler.call(this, event);"

请注意,像您这样将事件处理程序内联绑定是糟糕的设计,因为它将表示与应用程序逻辑混合在一起。还有另外两种方法可以绑定事件处理程序


我建议阅读quirksmode.org上关于事件处理的文章。

除了onMouseOver和onMouseOut,还有onMouseEnteronMouseLeave的概念。实际上我不知道它是如何implemented在不同的浏览器。我使用jQuery,它为我做了所有的事情。这里有一个很好的例子,当在页面底部使用不同的事件时会发生什么。