97

How can I trigger a function when I click anywhere on my page except on one div (id=menu_content) ?

jkdev
  • 11,360
  • 15
  • 54
  • 77
Vincent Roye
  • 2,751
  • 7
  • 33
  • 53

6 Answers6

161

You can apply click on body of document and cancel click processing if the click event is generated by div with id menu_content, This will bind event to single element and saving binding of click with every element except menu_content

$('body').click(function(evt){    
       if(evt.target.id == "menu_content")
          return;
       //For descendants of menu_content being clicked, remove this check if you do not want to put constraint on descendants.
       if($(evt.target).closest('#menu_content').length)
          return;             

      //Do processing of click event here for every element except with id menu_content

});
Adil
  • 146,340
  • 25
  • 209
  • 204
  • 4
    what about descendant childs in the DIV? – zEn feeLo Oct 23 '13 at 19:06
  • 2
    We can use closest to check of source of event has any ancestor with id menu_content like if($(evt.target).closest('#menu_content').length) retrun; check my updated answer. – Adil Jul 01 '14 at 04:28
  • Since `closest` begins with the current element, it handles clicking on `menu_content`, as well as clicking on descendents. I think the second `if` is all you need. – goodeye Nov 16 '18 at 02:11
  • if ($(evt.target).closest('#menu_content').length) { return; } Somehow bootstrap 3.3 doesn't work for me in a modal window. Cannot find closest(). Always .length == 0 – Andris Briedis Nov 06 '22 at 21:43
51

See the documentation for jQuery Event Target. Using the target property of the event object, you can detect where the click originated within the #menu_content element and, if so, terminate the click handler early. You will have to use .closest() to handle cases where the click originated in a descendant of #menu_content.

$(document).click(function(e){

    // Check if click was triggered on or within #menu_content
    if( $(e.target).closest("#menu_content").length > 0 ) {
        return false;
    }

    // Otherwise
    // trigger your click function
});
nbrooks
  • 18,126
  • 5
  • 54
  • 66
46

try this

 $('html').click(function() {
 //your stuf
 });

 $('#menucontainer').click(function(event){
     event.stopPropagation();
 });

you can also use the outside events

Database_Query
  • 626
  • 4
  • 14
  • 6
    This work, but using event.stopPropagation() can have knock on effects on other JS contained within the parent. – Edd Aslin Jul 06 '15 at 12:16
12

I know that this question has been answered, And all the answers are nice. But I wanted to add my two cents to this question for people who have similar (but not exactly the same) problem.

In a more general way, we can do something like this:

$('body').click(function(evt){    
    if(!$(evt.target).is('#menu_content')) {
        //event handling code
    }
});

This way we can handle not only events fired by anything except element with id menu_content but also events that are fired by anything except any element that we can select using CSS selectors.

For instance in the following code snippet I am getting events fired by any element except all <li> elements which are descendants of div element with id myNavbar.

$('body').click(function(evt){    
    if(!$(evt.target).is('div#myNavbar li')) {
        //event handling code
    }
});
Munim Munna
  • 17,178
  • 6
  • 29
  • 58
Gandalf
  • 2,921
  • 5
  • 31
  • 44
  • 1
    I just wanted to say that this method worked for me just fine, I used .is() and also .closest() with a css selector that had no ID but just some classes thank you – relipse Oct 10 '16 at 22:11
7

here is what i did. wanted to make sure i could click any of the children in my datepicker without closing it.

$('html').click(function(e){
    if (e.target.id == 'menu_content' || $(e.target).parents('#menu_content').length > 0) {
        // clicked menu content or children
    } else {
        // didnt click menu content
    }
});

my actual code:

$('html').click(function(e){
    if (e.target.id != 'datepicker'
        && $(e.target).parents('#datepicker').length == 0
        && !$(e.target).hasClass('datepicker')
    ) {
        $('#datepicker').remove();
    }
});
Nate
  • 71
  • 1
  • 2
1

You could try this:

$(":not(#menu_content)").on("click", function(e) {
    e.stopPropagation();
    // Run your function when clicked anywhere except #menu_content
    // Use with caution, 'cause it will prevent clicking on other elements
});

$("#menu_content").on("click", function(e) {
    e.stopPropagation();
    // Run when clicked on #menu_content
});
mXaln
  • 105
  • 11