在jQuery mousedown处理程序中添加叠加层后,Internet Explorer泄漏了单击事件

在div的mousedown事件处理程序中,创建另一个新div并将其附加到正文。
这个新的div具有position:fixed (也可以是position:absolute )并且具有100%宽度和100%高度。 因此它立即覆盖触发鼠标按下事件的源div。 现在使用最新的谷歌浏览器(v30),最新的Firefox(v24),Opera v12.16甚至是旧版的Safari v5.1.1(在Windows上),在mousedown事件之后, 没有点击事件会在附加到身体的事件监听器上触发。
之后只有 Internet Explorer(9和10) 才会触发正文上的click事件! 为什么? 如何防止这种情况? 这实际上是IE中的一个错误吗?

HTML:

 
Click me

CSS:

 .clickme { background-color: #BBB; } .overlay { position: fixed; /* or absolute */ left: 0; top: 0; height: 100%; width: 100%; background-color: #000; } 

JavaScript:

 $(document).on('click', function(event) { console.log('body click'); }); $('.clickme').on('mousedown', function(event) { console.log('div mousedown'); var mask = $('
'); mask.attr('class', 'overlay'); mask.appendTo('body'); });

这是一个带有一些额外评论的例子: http : //jsfiddle.net/Fh4sK/5/

单击“单击我”div后,仅

 div mousedown 

应该写入控制台,但在Internet Explorer中它实际上是

 div mousedown body click 

我感谢任何帮助! 谢谢!

编辑1:

我找到了一些描述触发点击事件的条件的资源:

http://www.quirksmode.org/dom/events/click.html :
“click – 在同一元素上发生mousedown和mouseup事件时触发。”

http://www.w3.org/TR/DOM-Level-3-Events/#events-mouseevent-event-order
“…通常应该在相关的mousedown和mouseup事件的事件目标是相同的元素时触发click和dblclick事件,没有mouseout或mouseleave事件干预,并且应该在事件发生时触发最近的共同祖先上的click和dblclick事件相关的mousedown和mouseup事件的目标是不同的。“

我不是100%确定现在的“正确”行为应该是什么(也许IE是唯一能够处理它的浏览器吗?)。 从最后一句开始,似乎在主体上触发click事件是正确的,因为body是两个div元素的“最近共同祖先”。 在上面引用的w3.org页面上还有一些其他语句,它们描述了元素被删除时的行为,但是我不确定这是否适用于此,因为没有元素被删除,但被其他元素覆盖。

编辑2:

@Evan打开了一个错误报告,要求微软放弃所描述的行为: https ://connect.microsoft.com/IE/feedback/details/809003/unexpected-click-event-triggered-when-the-elements-below-cursor- 在-鼠标按下-和鼠标松开事件,是-不同

编辑3:

除了Internet Explorer之外,Google Chrome最近也开始出现相同的行为: https : //code.google.com/p/chromium/issues/detail?id = 484655

我也碰到了这个问题。 我决定制作一个jQuery插件来解决这个问题并将它放在GitHub上。

一切都在这里,欢迎提供反馈: https : //github.com/louisameline/XClick

@mkurz:谢谢你找到W3指令,你为我节省了很多时间。 @vitalets:我解决了这个问题,因为我像你一样使用select2(你引导我到这个主题)。 我将分叉select2 repo并为感兴趣的人留言。

我会看看我是否可以要求微软的人看看它,并希望改变那种烦人的点击行为。

我也在努力应对这种行为。 我已经修改了你的小提琴,以了解如何使用动态创建的叠加触发所有鼠标事件:

http://jsfiddle.net/Fh4sK/9/

所以,当某个元素的mousedown处理程序显示覆盖在mousedown发生的同一个地方时:
Chrome,FF:

  1. mousedown触发了元素
  2. 在叠加层上触发鼠标
  3. click不会触发

IE:

  1. mousedown触发了元素
  2. 在叠加层上触发鼠标
  3. click 在BODY上触发(!)

如果您在mousedown中隐藏掩码,则会出现相同的行为。

这个问题可能导致IE中的模态,掩码,覆盖等奇怪的事情。

有趣的事情:如果你在mouseup显示叠加而不是mousedown – 一切正常

我找到的解决方案是使用mouseup而不是mousedown
它无法正常解释,因为这些事件都是 click 之前触发的。
在这种情况下,所有鼠标事件都在元素上触发:

http://jsfiddle.net/Fh4sK/11/

  1. mousedown触发了元素
  2. 在元素上触发mouseup
  3. click触发元素

希望这可以帮助。

您可以按目标过滤文档点击以排除该div上的点击:

 $(document).on('click', function(event) { if(!$(event.target).hasClass('clickme')) { console.log('body click'); } }); 

如果你想停止冒泡点击事件,试试这个:(我没有IE测试)

 $(document).on('click', function(event) { console.log('body click'); }); $('.clickme').on('mousedown', function(event) { console.log('div mousedown'); }); $('.clickme').on('click', function(event) { event.stopPropagation(); }); 

Click,mousedown和mouseup是不同的事件,独立。 这是一个类似的问题