如何在 Javascript 中移动子元素时触发一次鼠标事件?

Posted

技术标签:

【中文标题】如何在 Javascript 中移动子元素时触发一次鼠标事件?【英文标题】:How to fire mouse event once for moving over child elements in Javascript? 【发布时间】:2012-06-27 11:54:41 【问题描述】:

当输入一个 DOM 元素时,mouseover 事件将会发生。在当前元素周围移动鼠标时,不会发生任何事件,因为mouseover 用于输入。

但是,子节点不遵守此规则。如果将鼠标移到子节点上,mouseover 事件将一次又一次地触发,虽然没有新的事件,因为我们仍然在原来的父节点中。

看到这个example。如果我们将鼠标移到父元素上(实际上是在它的 textNode 上),没有任何新的事情发生,但是如果我们转到子元素(仍然在父元素上),它将一次又一次地触发 mouseover 事件。事实上,它会在鼠标每次进入元素时触发鼠标事件(即使在原始父元素内)。

我们如何使mouseover 只移动一次以在整个父级(addEventListener 中的原始元素)上移动?在给定的示例中,我的意思是避免在子元素上移动鼠标时触发事件。

【问题讨论】:

【参考方案1】:

这在 chrome 和 ff 中对我有用

document.getElementById("parent").addEventListener('mouseover', function(event) 
    var e = event.fromElement || event.relatedTarget;
    if (e.parentNode == this || e == this) 
        return;
    
    document.getElementById("time").innerhtml = new Date();
, true);

Fiddle Demo

参考:Mouse Events

【讨论】:

【参考方案2】:

您真正需要的是mouseenter 事件,它不会冒泡(与mouseover 不同)。来自 MDN:

同步 mouseenter DOM 事件在鼠标或 另一个指点设备进入分配给元素的物理空间 或其后代之一。

与 mouseover 类似,不同之处在于 不会冒泡 和 当指针从其后代之一移动时不会发送它 物理空间到它自己的物理空间。

不幸的是,它是not widely supported。一种解决方案是使用 jQuery(参见 .mouseenter()),它在它支持的所有浏览器中填充该事件。另一种选择是检查触发事件的元素:

document.getElementById("parent").addEventListener('mouseover', function(e) 
    if (e.target.id === "parent")  //Only execute following on parent mouseover
        document.getElementById("time").innerHTML = new Date;
        this.childNodes[1].style.display="block";
    
, false);

或see here 乍一看是一个相当不错的垫片。

【讨论】:

mouseenter 事件只针对 IE,我说的是纯 JS,不是 jQuery 框架。 @Ali - mouseenter 实际上在规范中,现在在 Firefox、IE 和 Opera 中得到支持。希望其他浏览器能尽快赶上。 但它仍然很快被用作流行事件,大多数用户(包括我)使用webkit浏览器。 @Ali - 同意,我也使用 WebKit 浏览器。我已经通过链接更新了我的答案,该链接指向一篇似乎有很好垫片的文章。我建议尝试一下。【参考方案3】:

在您的示例中,子元素没有触发任何事件,它是您的父元素,当您将鼠标悬停在其上时,它会运行您的脚本并在您的“时间”div 中显示结果。

【讨论】:

进入子元素会触发事件,因为我们还没有离开父元素。 @Ali 但脚本在 id 基础上运行。

以上是关于如何在 Javascript 中移动子元素时触发一次鼠标事件?的主要内容,如果未能解决你的问题,请参考以下文章

js点击事件

阻止 Javascript 事件影响子元素

JavaScript 事件类型,事件绑定,事件监听

jq 在iframe中点击按钮,父元素触发事件

mouseover mouseleave

javascript --- 鼠标事件