最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Multiple mouseout events triggered - Stack Overflow

programmeradmin2浏览0评论

I'm aware of the different event models in JavaScript (the WC3 model versus the Microsoft model), as well as the difference between bubbling and capturing. However, after a few hours reading various articles about this issue, I'm still unsure how to properly code the following seemingly simple behavior:

If I have an outer div and an inner div element, I want a single mouse-out event to be triggered when the mouse leaves the outer-div. When the mouse crosses from the inner-div to the outer-div, nothing should happen, and when the mouse crosses from the outer-div to the inner-div nothing should happen. The event should only fire if the mouse moves from the outer-div to the surrounding page.

<div id="outer" style = "width:20em; height:20em; border:1px solid #F00" align = "center" onmouseout="alert('mouseout event!')" >
<div id="inner" style = "width:18em; height:18em; border:1px solid #000"></div>
</div>

Now, if I place the mouseout event on the outer-div, two mouse-out events are fired when the mouse moves from the inner-div to the surrounding page, because the event fires once when the mouse moves from inner to outer, and then again when it moves from outer to the surrounding page.

I know I can cancel the event using ev.stopPropagation(), so I tried registering an event handler with the inner-div to cancel the event propagation. However, this won't prevent the event from firing when the mouse moves from the outer-div to the inner-div.

So, unless I'm overlooking something, it seems to me this behavior can't be acplished without plex mouse-tracking functions. In the future, I plan to re-implement a lot of this code using a more advanced framework, like jQuery, but for now, I'm wondering if there is a simple way to implement the above behavior in regular JavaScript.

I'm aware of the different event models in JavaScript (the WC3 model versus the Microsoft model), as well as the difference between bubbling and capturing. However, after a few hours reading various articles about this issue, I'm still unsure how to properly code the following seemingly simple behavior:

If I have an outer div and an inner div element, I want a single mouse-out event to be triggered when the mouse leaves the outer-div. When the mouse crosses from the inner-div to the outer-div, nothing should happen, and when the mouse crosses from the outer-div to the inner-div nothing should happen. The event should only fire if the mouse moves from the outer-div to the surrounding page.

<div id="outer" style = "width:20em; height:20em; border:1px solid #F00" align = "center" onmouseout="alert('mouseout event!')" >
<div id="inner" style = "width:18em; height:18em; border:1px solid #000"></div>
</div>

Now, if I place the mouseout event on the outer-div, two mouse-out events are fired when the mouse moves from the inner-div to the surrounding page, because the event fires once when the mouse moves from inner to outer, and then again when it moves from outer to the surrounding page.

I know I can cancel the event using ev.stopPropagation(), so I tried registering an event handler with the inner-div to cancel the event propagation. However, this won't prevent the event from firing when the mouse moves from the outer-div to the inner-div.

So, unless I'm overlooking something, it seems to me this behavior can't be acplished without plex mouse-tracking functions. In the future, I plan to re-implement a lot of this code using a more advanced framework, like jQuery, but for now, I'm wondering if there is a simple way to implement the above behavior in regular JavaScript.

Share Improve this question edited Apr 14, 2023 at 16:10 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Apr 24, 2010 at 16:16 Channel72Channel72 851 silver badge4 bronze badges 1
  • Does the page perhaps treat elements as bined? Like the outer-div itself would just be "outer-div" and then the inner-div inside of it would be "outer-div+inner-div", so if you cross between them it treats them as two separate ones, both with an onmouseout event attached to both of them? Seems kind of odd but that seems to be how the pages are working here. – animuson Commented Apr 24, 2010 at 16:22
Add a ment  | 

1 Answer 1

Reset to default 7

The mouseout event on the inner div ‘bubbles’ to the outer div. To detect that this has happened from the outer div, check the target property of the event:

<div id="outer">
    <div id="inner">x</div>
</div>
document.getElementById('outer').onmouseout= function(event) {
    // deal with IE nonsense
    if (event===undefined) event= window.event;
    var target= 'target' in event? event.target : event.srcElement;

    if (target!==this) return;
    ...
};

The usual problem with mouseout is you get it when the pointer moves “out” of the parent even if it's only moving “in” to the child. You can detect this case manually by looking up the ancestor list of the element the mouse is moving into:

    var other= 'relatedTarget' in event? event.relatedTarget : event.toElement;
    while ((other= other.parentNode).nodeType===1)
        if (other===this) return;

This is the mousein/mouseout model: it is only interested about which element is the mouse's immediate parent. What you more often want is the mouseenter/mouseleave model, which considers element trees as a whole, so you'd only get mouseleave when the pointer was leaving the element-or-its-descendants and not moving directly into the element-or-its-descendants.

Unfortunately mouseenter/mouseleave is currently an IE-only event pair. Hopefully other browsers will pick it up as it is expected to be part of DOM Level 3 Events.

发布评论

评论列表(0)

  1. 暂无评论