Internet Explorer 在 jQuery 鼠标向下处理程序中添加覆盖层后泄漏单击事件
Internet Explorer leaks click event after adding an overlay in a jQuery mousedown handler
在div 的mousedown
事件处理程序中,将创建另一个新div 并将其附加到 body.
这个新的div有position:fixed
(也可以position:absolute
(,并且具有100%的宽度和100%的高度。因此,它立即覆盖触发鼠标按下事件的源div。现在使用最新的Google Chrome(v30(,最新的Firefox(v24(,Opera v12.16,甚至在鼠标关闭事件后使用较旧的Safari v5.1.1(在Windows上(,在鼠标按下事件后,不会在附加到body的事件侦听器上触发点击事件.
只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/
单击"单击我"div后,仅
div mousedown
应该写入控制台,但在 Internet Explorer 中它实际上是
div mousedown
body click
我感谢任何帮助!
编辑 1:
我找到了一些描述何时触发点击事件的条件的资源:
http://www.quirksmode.org/dom/events/click.html:"单击 - 在同一元素上发生鼠标按下和鼠标向上事件时触发。">
http://www.w3.org/TR/DOM-Level-3-Events/#events-mouseevent-event-order"...通常,当关联的鼠标按下和鼠标悬停事件的事件目标是同一元素且没有鼠标退出或鼠标离开事件干预时,应触发单击和dblclick事件,当关联的鼠标按下和鼠标向上事件的事件目标不同时,应在最近的共同祖先上触发单击和dblclick事件。
我不是 100% 确定现在的"正确"行为实际上应该是什么(也许 IE 是唯一正确处理它的浏览器?从最后一句话来看,在 body 上触发 click 事件似乎是正确的,因为 body 是两个div 元素的"最近的共同祖先"。上面引用的 w3.org 页面上还有其他一些语句,它们描述了删除元素时的行为,但我不确定这是否适用于这里,因为没有元素被删除,但被其他元素覆盖。
编辑2:
@Evan打开了一个错误报告,要求Microsoft放弃所描述的行为: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
我也遇到了这个问题。我决定做一个jQuery插件来解决这个问题,并将其放在GitHub上。
都在这里,欢迎反馈:https://github.com/louisameline/XClick
@mkurz : 感谢您找到 W3 指令,您为我节省了很多时间。@vitalets :我解决了这个问题,因为我像你一样使用 select2(你把我带到了这个话题(。我将分叉 select2 存储库,并为对此感兴趣的人留言。
我会看看我是否可以要求Microsoft的人看看它,并希望改变这种烦人的点击行为。
我也为这种行为而挣扎。我已经修改了您的小提琴,以了解如何使用动态创建的叠加层触发所有鼠标事件:
http://jsfiddle.net/Fh4sK/9/
因此,当某个元素mousedown
处理程序在发生鼠标按下的同一位置显示覆盖时:
铬,FF:
- 在元素上触发
mousedown
- 叠加时触发
mouseup
-
click
不会触发
即:
-
mousedown
在元素上触发 - 叠加时触发
mouseup
-
click
在 BODY(!
如果在鼠标按下时隐藏掩码,则会出现相同的行为。
此问题可能会导致IE中出现模态,蒙版,覆盖层等奇怪的事情。
有趣的事情:如果您在mouseup
而不是mousedown
中显示叠加层 - 一切正常
我找到的解决方案是使用 mouseup
而不是 mousedown
.
通常无法解释,因为这两个事件都是在click
之前触发的。
在这种情况下,所有鼠标事件都会在元素上触发:
http://jsfiddle.net/Fh4sK/11/
- 在元素上触发
mousedown
- 在元素上触发
mouseup
- 在元素上触发
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();
});
单击、鼠标向下和鼠标向上是不同的事件,独立。这是一个类似的问题
- 将添加一个相同类型的事件附加或覆盖以前添加的具有相同名称的事件
- javascript函数将数据添加到屏幕,但随后被另一个函数覆盖
- 如何将可调整大小、可拖动的覆盖添加到网页中
- 如何在视频标签中添加按钮覆盖
- 如何在不覆盖的情况下添加同一JPanel类的不同实例
- 将角度控制器添加到因果报应覆盖(伊斯坦布尔)代码覆盖预处理器
- 将覆盖添加到除元素之外的主体
- 在覆盖和关闭按钮或链接中为img添加边框
- 如何覆盖Asp.Net UpdatePanel(动态)添加的Javascript函数
- javascript原生原型:扩展、添加和覆盖方法
- 使用 CSS 覆盖通过 JS 添加的内联样式
- Internet Explorer 在 jQuery 鼠标向下处理程序中添加覆盖层后泄漏单击事件
- 在覆盖层上添加事件侦听器
- 添加事件侦听器而不覆盖
- jQuery:在调整窗口大小时添加和删除元素,但始终覆盖窗口
- 如何覆盖 Backbone.sync,以便在末尾添加 apikey 和用户名
- 我想克隆一个 javascript 类. 将方法添加到克隆的属性中,而不实际覆盖现有方法
- 添加但不覆盖文本
- AngularJS-自动向URL添加哈希标签-覆盖搜索参数
- 无法使用图像覆盖添加bing主题