Reputation: 345
I have question, why JQuery ignores .not in this code:
$('body').not('#footer').on('click',function(){
if (($('#footer')).is(":visible")) {
$('#footer').fadeOut();
}
});
Basicly, i want to close #footer, but only by click on other elements than #footer. The code above does his job, but clicking on #footer also fadeOut this element, and this is not desired.
Ond on other side, this will work:
$('div').not('#footer').on('click',function(){
if (($('#footer')).is(":visible")) {
$('#footer').fadeOut();
}
});
Now the downside is, that if i click on div inside #footer, this will also close it, so not perfect solution.
My question is, how i can target all elements to close #footer, but not #footer and his childern.
Thank You for advice.
I have used this selector : $('body').children().not('#footer').on('click',function(){ This above, now closes #footer only when i click on body not #footer itself.
But now, clicking on element lef or right margin does nothing.
Screen to be more precisly, in image.
Upvotes: 0
Views: 86
Reputation: 136094
why JQuery ignores .not in this code
Because your body element does not have the id footer but some of your div elements obviously do!
You could do this:
$('div:not(#footer)').on('click',function(){
// if we're not a child of footer and footer is visible
if ($(this).parents('#footer').length == 0 && ($('#footer')).is(":visible")) {
$('#footer').fadeOut();
}
});
or a better solution is:
$('body').on('click',':not(#footer)',function(){
// as above
});
As this does not bind an event to every non footer div on the page.
Or you can roll all the work into the delegate's selector to keep it concise.
$('body').on('click',':not(#footer,#footer>*)',function(){
$("#footer").fadeOut();
});
Just keep in mind that with these delegate solutions, there is significant overhead since for every click on the page the handler will run, not just once, but once for the event.target
and each of its .parentNode
s.
So in each case, the selector will run and traverse up to the body
to see if the element is in #footer
.
This means that if you click a node nested 20 elements deep, it'll start on the event.target
, traverse up those 20 nodes and see that it's not in the #footer
. Then it'll start again on the .parentNode
of the event.target
and traverse up 19 nodes, then up 18, then 17 and so on.
Furthermore, the .fadeOut()
will end up being called multiple times
So you can see that this is pretty inefficient overall.
Also keep in mind that these solutions require that #footer
is a direct child of body
. If there's some parent element before the body
, it'll fade out.
Upvotes: 9
Reputation: 3112
If you want to apply the click function to all elements within body
(except #footer
) then replace -
$('body').not('#footer').on('click',function(){
With -
$('body').children().not('#footer').on('click',function(){
Upvotes: 1