6

我正在尝试设置一个在单击没有.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") );
});

​( jsFiddle 演示)

这也不起作用:

$("html").not('.four').on("click", function(e){

两个输出:Something without class 'four' was clicked that had class: four

我遇到了很多麻烦,:not()我怀疑很多可能与我:not()现在支持 CSS3 的浏览器有关,但我仍然无法理解这个简单的问题。

4

4 回答 4

6

你的代码:

$("html").one("click", ":not(.four)", function(e){
    e.stopPropagation();
    // other code
});

为点击事件类型设置全局事件委托。这意味着每当页面上的任何元素触发 click 事件时,jQuery 都会检查该元素是否与提供的选择器匹配":not(.four)"- 如果匹配,jQuery 将调用该元素上的处理程序。

当您单击一个.four元素时会发生以下情况:

  1. 触发点击事件的原始元素显然是.four元素。jQuery 检查该元素是否与":not(.four)"选择器匹配。因为它没有,所以不会在该元素上调用处理程序。

  2. 点击事件在 DOM 树中冒泡。由于尚未取消此单击事件的传播,因此该事件在下一个元素处触发,该元素是原始元素的父元素 -.two您演示中的元素。同样,jQuery 检查元素是否与选择器匹配。既然这样做了,就会在该元素上调用处理程序。

如您所见,即使您单击一个元素,也会调用您的处理程序。.four为了防止在.four单击元素时执行代码,您必须在处理程序中显式检查 - 基本上是 Jason 的解决方案所做的。

于 2013-01-01T01:53:05.530 回答
2

Here is a solution I want to contribute. Put this listener alongside the other one:

$("html").one("click", ".four", function(e){
       e.stopPropagation();
});
$("html").one("click", function(e){
    // other code
});

It will prevent propagation on .four and "steal" or "catch" it from bubbling up to the other listener. It might be helpful to have the "catcher" listener at a lower level than the other one, depending on if it bubbles up to one before the other.

See the jsFiddle demo, working, finally!

于 2013-01-01T02:19:56.177 回答
2

正如 Šime Vidas 指出的那样,这是理想的解决方法:

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);
于 2013-01-01T01:22:14.267 回答
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()将匹配类的孩子以及类元素本身

于 2013-01-01T02:15:41.703 回答