我知道Javascript中的不同事件模型(WC3模型与Microsoft模型),以及冒泡和捕获之间的区别。但是,经过几个小时阅读有关此问题的各种文章后,我仍然不确定如何正确编码以下看似简单的行为:
如果我有一个外部div
和一个内部div
元素,我想要在鼠标离开外部div时触发一个鼠标移出事件。当鼠标从内部div跳到外部div时,什么都不应该发生,当鼠标从外部div跨越到内部div时,什么都不应该发生。如果鼠标从外部div移动到周围页面,该事件应仅触发。
<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>
现在,如果我将“mouseout”事件放在outer-div上,当鼠标从inner-div移动到周围页面时会触发两个鼠标移出事件,因为事件当鼠标从内部移动到外部时触发一次,然后当它从外部移动到周围页面时再触发一次。
我知道我可以使用ev.stopPropagation()
取消事件,所以我尝试使用inner-div注册一个事件处理程序来取消事件传播。但是,当鼠标从外部div移动到内部div时,这不会阻止事件触发。
所以,除非我忽略了某些东西,否则在我看来,如果没有复杂的鼠标跟踪功能,这种行为是无法实现的。在将来,我计划使用更高级的框架(如JQuery)重新实现许多代码,但是现在,我想知道是否有一种简单的方法可以在常规Javascript中实现上述行为。
答案 0 :(得分:6)
内部div上的mouseout
事件'冒泡'到外部div。要检测外部div发生了这种情况,请检查target
的{{1}}属性:
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;
...
};
的常见问题是,当指针向父母“移出”时,即使它只是向孩子“移入”,也会得到它。您可以通过查找鼠标移动到的元素的祖先列表来手动检测此案例:
mouseout
这是 var other= 'relatedTarget' in event? event.relatedTarget : event.toElement;
while ((other= other.parentNode).nodeType===1)
if (other===this) return;
/ mousein
模型:它只关心哪个元素是鼠标的直接父元素。你经常想要的是mouseout
/ mouseenter
模型,它将元素树视为一个整体,所以当指针离开元素或者它时,你只能获得mouseleave
-descendants并且不直接移动到元素或它的后代。
不幸的是,mouseleave
/ mouseenter
目前是仅限IE的事件对。希望其他浏览器能够接收它,因为它有望成为DOM Level 3 Events的一部分。