admin管理员组文章数量:1335585
I'm trying to set an event that fires when anything WITHOUT the .four
class is clicked. However, it fires when things with the .four
class are clicked, even though I'm using 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 Demo)
This does not work either:
$("html").not('.four').on("click", function(e){
Both output: Something without class 'four' was clicked that had class: four
I'm having tons of trouble with :not()
and I suspect a lot of it might have to do with my browser supporting CSS3 :not()
now, but I still can't understand this simple issue.
I'm trying to set an event that fires when anything WITHOUT the .four
class is clicked. However, it fires when things with the .four
class are clicked, even though I'm using 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 Demo)
This does not work either:
$("html").not('.four').on("click", function(e){
Both output: Something without class 'four' was clicked that had class: four
I'm having tons of trouble with :not()
and I suspect a lot of it might have to do with my browser supporting CSS3 :not()
now, but I still can't understand this simple issue.
- +1 Good question. I'm on it. – Šime Vidas Commented Jan 1, 2013 at 1:27
-
So you just want to ensure that when
.four
is clicked that the event doesn't fire, right? I'm just trying to be clear. – Ohgodwhy Commented Jan 1, 2013 at 1:47 -
@Ohgodwhy Yes, every element on the page except
.four
should have a click event delegated byhtml
. – Jason Whitted Commented Jan 1, 2013 at 1:49
4 Answers
Reset to default 6Your code:
$("html").one("click", ":not(.four)", function(e){
e.stopPropagation();
// other code
});
sets up global event delegation for the click event type. This means that whenever a click event is triggered at any element on the page, jQuery will check if that element matches the provided selector - ":not(.four)"
- and if it does, jQuery will invoke the handler on that element.
This is what happens when you click on a .four
element:
The original element at which the click event is triggered is obviously the
.four
element. jQuery checks if that element matches the":not(.four)"
selector. Since it doesn't, the handler is not invoked on that element.Click events bubble up the DOM tree. As propagation for this click event has not been canceled yet, the event triggers at the next element, which is the parent of the original element - the
.two
element in your demo. Again, jQuery checks if the element matches the selector. Since it does, the handler is invoked on that element.
As you can see, your handler will be invoked even if you click on a .four
element. In order to prevent the code from being executed when a .four
element is clicked, you have to explicitly check within the handler - basically what Jason's solution does.
As Šime Vidas pointed out, this is the desired workaround:
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);
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!
Here's another approach using the event 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()
will match children of the class as well as the class element itself
本文标签: javascriptWhy isn39t the jquery not() selector working as I expect it toStack Overflow
版权声明:本文标题:javascript - Why isn't the jquery :not() selector working as I expect it to? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742384526a2464760.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论