How do I handle a click anywhere in the page, even when a certain element stops the propagation?

javascript click anywhere except element
addeventlistener
jquery click outside div
detect click outside element
click on body except div jquery
onclick javascript
window body click
click event

We are working on a JavaScript tool that has older code in it, so we cannot re-write the whole tool.

Now, a menu was added position fixed to the bottom and the client would very much like it to have a toggle button to open and close the menu, except closing needs to happen automatically when a user starts doing things out side of the menu, for example, when a user goes back into the page, and selects something or clicks on a form field.

This could technically work with a click event on the body, triggering on any click, however there are numerous items in the older code, where a click event was handled on an internal link, and return false was added to the click function, in order for the site not to continue to the link's href tag.

So clearly, a general function like this does work, but not when clicked on an internal link where the return false stops the propagation.

$('body').click(function(){
  console.log('clicked');
});

Is there a way I can force the body click event anyway, or is there another way I can let the menu dissappear, using some global click event or anything similar?

Without having to rewrite all other clicks in the application that were created years ago. That would be a monster task, especially since I have no clue how I would rewrite them, without the return false, but still don't let them go to their href.

Events in modern DOM implementations have two phases, capturing and bubbling. The capturing phase is the first phase, flowing from the defaultView of the document to the event target, followed by the bubbling phase, flowing from the event target back to the defaultView. For more information, see http://www.w3.org/TR/DOM-Level-3-Events/#event-flow.

To handle the capturing phase of an event, you need to set the third argument for addEventListener to true:

document.body.addEventListener('click', fn, true); 

Sadly, as Wesley mentioned, the capturing phase of an event cannot be handled reliably, or at all, in older browsers.

One possible solution is to handle the mouseup event instead, since event order for clicks is:

  1. mousedown
  2. mouseup
  3. click

If you can be sure you have no handlers cancelling the mouseup event, then this is one way (and, arguably, a better way) to go. Another thing to note is that many, if not most (if not all), UI menus disappear on mouse down.

The Dangers of Stopping Event Propagation, He is going to explain why stopping event propagation isn't something you dialog that dismissed itself after the user clicked anywhere else on the page. rundown: If a click event propagates to the <html> element, hide the menus. You might be thinking to yourself: who even writes code like this themselves anymore? 1 How do I handle a click anywhere in the page, even when a certain element stops the propagation? Apr 26 '18. 1 Purpose of assert in NodeJS Dec 7 '17.

In cooperation with Andy E, this is the dark side of the force:

var _old = jQuery.Event.prototype.stopPropagation;

jQuery.Event.prototype.stopPropagation = function() {
    this.target.nodeName !== 'SPAN' && _old.apply( this, arguments );
};     

Example: http://jsfiddle.net/M4teA/2/

Remember, if all the events were bound via jQuery, you can handle those cases just here. In this example, we just call the original .stopPropagation() if we are not dealing with a <span>.


You cannot prevent the prevent, no.

What you could do is, to rewrite those event handlers manually in-code. This is tricky business, but if you know how to access the stored handler methods, you could work around it. I played around with it a little, and this is my result:

$( document.body ).click(function() {
    alert('Hi I am bound to the body!');
});

$( '#bar' ).click(function(e) {
    alert('I am the span and I do prevent propagation');
    e.stopPropagation();
});

$( '#yay' ).click(function() {
    $('span').each(function(i, elem) {
        var events        = jQuery._data(elem).events,
            oldHandler    = [ ],
            $elem         = $( elem );

        if( 'click' in events ) {                        
            [].forEach.call( events.click, function( click ) {
                oldHandler.push( click.handler );
            });

            $elem.off( 'click' );
        }

        if( oldHandler.length ) {
            oldHandler.forEach(function( handler ) {
                $elem.bind( 'click', (function( h ) {
                    return function() {
                        h.apply( this, [{stopPropagation: $.noop}] );
                    };
                }( handler )));
            });
        }
    });

    this.disabled = 1;
    return false;
});

Example: http://jsfiddle.net/M4teA/

Notice, the above code will only work with jQuery 1.7. If those click events were bound with an earlier jQuery version or "inline", you still can use the code but you would need to access the "old handler" differently.

I know I'm assuming a lot of "perfect world" scenario things here, for instance, that those handles explicitly call .stopPropagation() instead of returning false. So it still might be a useless academic example, but I felt to come out with it :-)

edit: hey, return false; will work just fine, the event objects is accessed in the same way.

jQuery hide menu when user clicks anywhere, I've built a menu with some css and a little jQuery here. the menu when the user clicks anywhere else on the page excpet on the form elements? stopPropagation(); // this stops the event from bubbling up to the body });. 35 How do I handle a click anywhere in the page, even when a certain element stops the propagation? Nov 8 '11 31 Backbone.js: complex views combining multiple models Sep 12 '11

If you make sure that this is the first event handler work, something like this might do the trick:

$('*').click(function(event) {
    if (this === event.target) { // only fire this handler on the original element
        alert('clicked');
    }
});

Note that, if you have lots of elements in your page, this will be Really Very Slow, and it won't work for anything added dynamically.

Browser default actions, Many events automatically lead to certain actions performed by the browser. But normally we intend to handle clicks in JavaScript. it has first to process all handlers, and then if preventDefault is not called anywhere, it can proceed with scrolling. stopPropagation() and why stopping bubbling is bad? If I understand, you want to hide a div when you click anywhere but the div, and if you do click while over the div, then it should NOT close.

Detecting a Click Outside an Element in JavaScript, How do you hide a div when the user clicks outside of it using jQuery? If the click action causes a new page to load (like a link usually does), call waitForPageToLoad. 'locator' is an element locator 'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse event relative to the element returned by the locator.

this is the key (vs evt.target). See example.

document.body.addEventListener("click", function (evt) {
    console.dir(this);
    //note evt.target can be a nested element, not the body element, resulting in misfires
    console.log(evt.target);
    alert("body clicked");
});
<h4>This is a heading.</h4>
<p>this is a paragraph.</p>

How to Hide Div when Click Outside of the Element using jQuery , This approach calls a function when any click event happens. If it is other HTML element then do nothing. Else, use event.stopPropagation() method to stop the  How to detect a click outside an element? The reason that this question is so popular and has so many answers is that it is deceptively complex. After almost eight years and dozens of answers, I am genuinely surprised to see how little care has been given to accessibility.

Event Bubbling and Event Capturing in JavaScript, On the Introduction to events page I asked a question that at first sight seems If the user clicks on element2 he causes a click event in both element1 and element2. script explicitly orders the event to stop bubbling, it will not propagate to the document. you cannot know which HTML element currently handles the event. In that case I suspect scrolling the element will indeed not work when this code is used. Not because it is inside body but for the reason that all touchmove behaviour has been disabled. Then again, if it has overflow then swiping it will not bubble up and cause momentum page scrolling but ‘normal and local’ scrolling on the element.

JavaScript, For example, this code listens for a user to click on any li element in the page: Consider a situation where you bind some events, and then want to unbind in a space-separated string — followed by the function that you want to handle both but this actually has another side effect: it stops the propagation of the event as  Well organized and easy to understand Web building tutorials with lots of examples of how to use HTML, CSS, JavaScript, SQL, PHP, Python, Bootstrap, Java and XML.

How to click anywhere on the page except one element using jQuery, An element receives a click event when a pointing device button (such as a mouse's On this Page The MouseEvent object passed into the event handler for click has its detail property set Stop using click event delegation. Notes Only works for <textarea> elements and some <input> element types. Internet Explorer 8 & 9 suffer from a bug where elements with a computed background-color of transparent that are overlaid on top of other element(s) won't receive click events. Any click events will be fired at the underlying element(s) instead. See this live example for a demonstration.

Comments
  • For anyone wondering if they can use this, here is the caniuse page: caniuse.com/#feat=addeventlistener short answer is yes, as long as you don't care about IE8
  • the dynamic thing could be easily fixed via $("*").on("click", function() {}); but regardless this is a bad idea.
  • will that fire if something nested deeper in the dom prevents event propagation though?
  • I think the problem is that the click events are being swallowed by returning false from the event handlers on certain links, not that the click event couldn't be generated in the first place.