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

时间:2013-10-07 00:08:03

标签: javascript jquery internet-explorer dom javascript-events

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

HTML:

<div class="clickme">Click me</div>

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 = $('<div></div>');
    mask.attr('class', 'overlay');
    mask.appendTo('body');
});

以下是一个包​​含其他评论的示例:http://jsfiddle.net/Fh4sK/5/

单击“Click me”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事件的事件目标是相同的元素而没有mouseout或mouseleave事件干预时,通常应该触发click和dblclick事件,并且当事件发生时应触发最近的共同祖先上的click和dblclick事件相关的mousedown和mouseup事件的目标是不同的。“

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

编辑2:

@Evan打开了一个错误报告,要求微软放弃所描述的行为:https://connect.microsoft.com/IE/feedback/details/809003/unexpected-click-event-triggered-when-the-elements-below-cursor-at-mousedown-and-mouseup-events-are-different

编辑3:

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

4 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:1)

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

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

因此,当某个元素的mousedown处理程序显示覆盖在mousedown发生的同一位置时: Chrome,FF:

    元素上触发了
  1. mousedown
  2. mouseup已在叠加
  3. 上触发
  4. click不会触发
  5. IE:

      元素上触发了
    1. mousedown
    2. mouseup已在叠加
    3. 上触发
    4. click 在BODY(!)
    5. 上触发

      如果你在mousedown中隐藏了掩码,则会出现同样的行为。

      这个问题可能导致IE中出现奇怪的事情,包括模态,蒙版,叠加等。

      有趣的事情:如果您在mouseup而不是mousedown中显示叠加层 - 一切正常

      我发现的解决方案是使用mouseup代替mousedown
      它无法正常解释,因为这两个事件都是在 click之前触发的 在这种情况下,所有鼠标事件都在元素上触发:

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

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

        希望这有帮助。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

如果你想停止点击事件的冒泡,试试这个:(我没有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是不同的事件,独立。 here is a similar question