我正在尝试设置一个事件,当点击没有.four
类的任何内容时触发该事件。但是,即使我使用.four
,点击e.stopPropagation()
类的内容时也会触发。
$("html").one("click", ":not(.four)", function(e){
e.stopPropagation();
console.log("Something without class 'four' was clicked that had class: " + $(e.srcElement).attr("class") );
});
这也不起作用:
$("html").not('.four').on("click", function(e){
两个输出:Something without class 'four' was clicked that had class: four
我在使用:not()
时遇到了很多麻烦,我怀疑它可能与我的浏览器支持CSS3 :not()
现在有很多关系,但我仍然无法理解这个简单的问题。
答案 0 :(得分:6)
您的代码:
$("html").one("click", ":not(.four)", function(e){
e.stopPropagation();
// other code
});
为click事件类型设置全局事件委派。这意味着只要在页面上的任何元素触发click事件,jQuery就会检查该元素是否与提供的选择器匹配 - ":not(.four)"
- 如果匹配,jQuery将调用处理程序关于那个元素。
当您点击.four
元素时会发生这种情况:
触发click事件的原始元素显然是.four
元素。 jQuery检查该元素是否与":not(.four)"
选择器匹配。因为它没有,所以在该元素上调用处理程序 。
点击事件冒泡DOM树。由于此click事件的传播尚未取消,因此事件将触发下一个元素,即原始元素的父元素 - 演示中的.two
元素。同样,jQuery检查元素是否与选择器匹配。既然如此,就会在该元素上调用处理程序。
如您所见,即使您点击.four
元素,也会调用您的处理程序 。为了防止在单击.four
元素时执行代码,您必须在处理程序中明确检查 - 基本上是Jason的解决方案。
答案 1 :(得分:2)
正如ŠimeVidas所指出的,这是理想的解决方法:
function doThisOnce(e) {
e.stopPropagation();
if(!$(this).is(".four")){
console.log("Something without class 'four' was clicked that had class: " + $(e.srcElement).attr("class"));
$(".one").addClass("pretty");
}
else {
// need to rebind the click event
$(document).one("click", "*", doThisOnce);
}
}
$(document).one("click", "*", doThisOnce);
答案 2 :(得分:2)
这是我想要贡献的解决方案。把这个听众放在另一个旁边:
$("html").one("click", ".four", function(e){
e.stopPropagation();
});
$("html").one("click", function(e){
// other code
});
它会阻止.four
上的传播,并“窃取”或“捕获”它从冒泡到另一个侦听器。让“捕手”监听器处于比另一个更低的级别可能会有所帮助,具体取决于它是否在另一个之前冒泡。
最后看到jsFiddle demo,正在工作!
答案 3 :(得分:0)
以下是使用事件target
:
$(document).one("click", function(e){
if( ! $(e.target).closest('.four').length ){
console.log("Something without class 'four' was clicked that had class: " + $(e.srcElement).attr("class") );
}
});
closest()
将匹配类的子元素以及类元素本身