开发者

JQuery: click everywhere but some element

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(...)开发者_StackOverflow; 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).


$("body *:not(body #menu)").click()

Dont know if this will work, I'm not at my computer...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜