Javascript 当悬停的元素被另一个元素覆盖时,不触发mouseout

Javascript 当悬停的元素被另一个元素覆盖时,不触发mouseout,javascript,javascript-events,Javascript,Javascript Events,我最近发现javascript中的mouseout事件有一个奇怪的行为。 请看我的小提琴: 当我将鼠标悬停在按钮上方时,将触发mouseenter事件。当我离开按钮时,mouseout事件被触发。到目前为止还不错 现在,当我悬停,然后单击,单击事件显示一个div,该div放置在按钮上,mouseout事件也将被触发 但是,当使用setTimeout在短暂延迟后显示div时,mouseout事件将在我移动鼠标之前不会触发 你能给我解释一下这种行为吗 更新: 我把这个bug提交给chromium,他

我最近发现javascript中的
mouseout
事件有一个奇怪的行为。 请看我的小提琴:

当我将鼠标悬停在按钮上方时,将触发
mouseenter
事件。当我离开按钮时,
mouseout
事件被触发。到目前为止还不错

现在,当我悬停,然后单击,单击事件显示一个div,该div放置在按钮上,
mouseout
事件也将被触发

但是,当使用
setTimeout
在短暂延迟后显示div时,mouseout事件将在我移动鼠标之前不会触发

你能给我解释一下这种行为吗

更新: 我把这个bug提交给chromium,他们确认了。请看这里:


该漏洞也出现在Opera、Safari(常见的WebKit)和IE中。它似乎是一个模糊的浏览器漏洞(在Chrome中)
Firefox
似乎工作正常。我不确定其他浏览器

为了更清楚,我用原生js替换了所有内容:


我浏览了WebKit bugzilla,似乎是你的bug,你应该在bug中添加一个新的注释,并添加一个指向测试用例的链接,因为bug中链接的测试用例似乎丢失了(404错误)。

尝试在覆盖上使用委托来冒泡事件。
编辑 Fiddle今天速度很慢,我最初发布的Fiddle没有我使用的代码片段

这在选择jQuery版本(1.8.2)的情况下确实可以工作 链接到jsBIN fork:

编辑2 我刚刚意识到,没有div的鼠标/鼠标/鼠标/鼠标不工作。我已经更新了代码,所以现在它可以使用和不使用div覆盖

var fail = true;

var button = document.getElementById("button");
var overlay = document.getElementById("overlay");
var log = document.getElementById("log");


button.addEventListener('click', function() {
    if (fail) {

        // mouseout won't be fired until you move the mouse
        window.setTimeout(function() {
            overlay.style.display = 'block';
        }, 0);

    } else {

        // mouseout event is fired instantly
        overlay.style.display = 'block';

    }


    log.innerHTML += 'over' + "<br>";

}, false);

button.addEventListener('mouseover', function() {
    log.innerHTML += 'over' + "<br>";
}, false);

button.addEventListener('mouseout', function() {
    log.innerHTML += 'out' + "<br>";
}, false);

$(overlay).delegate(button, 'mouseover', function() {
        log.innerHTML += 'over' + "<br>";
});

$(overlay).delegate(button, 'mouseout', function() {
        log.innerHTML += 'out' + "<br>";
    });
var fail=true;
var button=document.getElementById(“按钮”);
var overlay=document.getElementById(“overlay”);
var log=document.getElementById(“日志”);
addEventListener('click',function(){
如果(失败){
//除非你移动鼠标,否则mouseout不会被触发
setTimeout(函数(){
overlay.style.display='block';
}, 0);
}否则{
//mouseout事件立即触发
overlay.style.display='block';
}
log.innerHTML+='在'+'
上; },假); addEventListener('mouseover',function(){ log.innerHTML+='在'+'
上; },假); addEventListener('mouseout',function(){ log.innerHTML+='out'+“
”; },假); $(覆盖).delegate(按钮'mouseover',函数(){ log.innerHTML+='在'+'
上; }); $(覆盖).delegate(按钮'mouseout',函数(){ log.innerHTML+='out'+“
”; });
解决此问题的最佳方法是包装按钮和覆盖层,并将mouseover和mouseleave更改为此包装层

//HTML

<div class="helper">
  <div class="overlay"></div>
  <button class="button">Foo</button>
</div>

只需鼠标移出事件覆盖并使其淡出或执行任何您希望它执行的操作。我在你的提琴里提醒过你试试看

  $$('.button').addEvent('mouseover', function() {
console.log('over');
}))


}))

这似乎是mouseout实现中的一个cornercase错误..IE9、Opera和Safari中的相同“错误”。我真的对这种行为背后的故事感兴趣。@JulianHollmann我添加了整个片段。我链接到的小提琴叉没有正确的代码。@朱利安·霍尔曼我对代码进行了另一次更新,以修复这两种情况(div overlay hidden/visible)。请试试。现在div也会触发事件,这不是故意的,对吧?你告诉我。我以为你的问题是这件事没有发生?这不是问题吗?问题是,按钮上的mouseout事件没有触发。这在某些浏览器中是一个bug。覆盖似乎是任意的。如果helper上有另一个DIV呢?我使用helper DIV只是为了避免内部HTML的mouseout事件。这意味着你可以在div中做任何你想做的事情,而不会失去鼠标悬停的效果。您可以在helper div周围任意包装。它不会有副作用
  $$('.button').addEvent('mouseover', function() {
console.log('over');
  $$('.overlay').addEvent('mouseout', function() {
   alert("ee");