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.
Your 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With