I have some elements which i can select with .click() function and they became highlighted. There is menu above them with some actions. I want to cancel highlight when I click any element but not menu.
Structure:
<body>
<div id="menu">
</div>
<div id="elements">
/* selectable elements here */
</div>
</body>
Executable Example
$().ready(function(){
$("#elements a").click(function(){
$(this).css('color', 'red');
return false;
});
$(document).click(function(e) {
if ( $(e.target).closest('#menu').length === 0 ) {
$("#elements a").css('color', 'blue');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu">
<a href="#">Menu 1</a>
<a href="#">Menu 2</a>
<a href="#">Menu 3</a>
</div>
<div id="elements">
<a href="#">Element 1</a>
<a href="#">Element 2</a>
<a href="#">Element 3</a>
</div>
<div>
Click any element to highlight it. Click anywhere to reset highlighting. Click menu to keep highlighting.
</div>
Jsfiddle
I tried to bind $("body *").not("#menu").click(...);
but when I click on #menu then body's onclick event fired too because #menu is body's children.
$(document).click(function(e) {
if ( $(e.target).closest('#menu').length === 0 ) {
// cancel highlighting
}
});
An alternative solution would be to call stopPropagation()
at the end of the #menu click handler and element click handlers. That way, if a click event bubbles to the document object, you know that neither the menu nor the elements were clicked and you can safely cancel the highlighting:
$('#menu').click(function(e) {
// do stuff
e.stopPropagation();
});
$('.element').click(function(e) {
//do stuff
e.stopPropagation();
});
$(document).click(function() {
// cancel highlighting
});
.closest will propagate and check if one of the parents is the unclickable element.
$(document).on('click', '.clickable_parent', function(e){
if(e.target.closest(".UnClickable_child") === null){
//do stuff
}
});
An alternative to writing your own delegated handler for this is to use Ben Almans "outside events" plugin to achieve this. Does pretty much the same thing mentioned by Šime Vidas but hey - choices are a good thing!
http://benalman.com/projects/jquery-outside-events-plugin/
So something like this
$('#menu').bind("clickoutside", function(){
// cancel highlighting
})
You should handle the click
event on body
, then check whether $.contains($('#menu'), e.target)
.
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