4

在 div 的 mousedown 事件处理程序中,会创建另一个新 div 并将其附加到主体。
这个新的 div 有position:fixed(也可以是position:absolute)并且有 100% 的宽度和 100% 的高度。因此它会立即覆盖触发鼠标按下事件的源 div。现在使用最新的 Google Chrome (v30)、最新的 Firefox (v24)、Opera v12.16,甚至使用较旧的 Safari v5.1.1(在 Windows 上),在 mousedown 事件之后,不会在附加到主体的事件侦听器上触发点击事件.
之后只有Internet Explorer(9 和 10)触发 body 上的 click 事件!为什么?如何防止这种情况发生?这实际上是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/

单击“单击我” 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 事件events 是相同的元素,没有 mouseout 或 mouseleave 事件介入,并且当关联的 mousedown 和 mouseup 事件的事件目标不同时,应该在最近的共同祖先上触发 click 和 dblclick 事件。"

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

编辑2:

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

编辑 3:

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

4

4 回答 4

2

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

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

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

我会看看我是否可以让微软的人来看看它,并希望能改变这种恼人的点击行为。

于 2013-11-18T16:30:31.570 回答
1

我也与这种行为作斗争。我已经修改了您的小提琴,以了解如何使用动态创建的叠加层触发所有鼠标事件:

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

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

  1. mousedown在元素上触发
  2. mouseup在叠加层上触发
  3. click不触发

IE:

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

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

这个问题可能会导致 IE 中出现模式、掩码、覆盖等奇怪的事情。

有趣的事情:如果你显示覆盖mouseup而不是mousedown- 一切正常

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

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

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

希望这可以帮助。

于 2013-11-03T17:49:18.310 回答
0

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

$(document).on('click', function(event) {
    if(!$(event.target).hasClass('clickme')) {
        console.log('body click');  
    }
});
于 2013-10-07T01:53:28.483 回答
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 是不同的事件,相互独立。 这是一个类似的问题

于 2013-10-07T14:08:05.520 回答