65Fbef05
65Fbef05

Reputation: 4522

Excessive Use of jQuery's preventDefault() and stopPropagation()

I was recently in a discussion with a work colleague about some differences in our coding practices, where I raised an issue about his excessive use of the two above mentioned methods in his event handlers. Specifically, they all look like this...

$('span.whatever').on('click', function(e) {

    e.preventDefault();
    e.stopPropagation();

    /* do things */

});

He has made the claim that this is a good practice with no foreseeable blowback, and will improve cross-platform support while reducing unexpected issues down the road.

My question to you guys: If he's right, why hasn't the jQuery team implemented this behavior globally applied to all event handlers? In effect, my assumption is that he's wrong simply because the methods are available for independent use, but who knows... Your insight is much appreciated.

--

Update: I did a simple speed test, and there is a little drag caused by these two function, but nothing terribly noticeable. Still, among other things, a good reason to be deliberate in their use I think.

$('span.whatever').on('click', function(e) {

    var start = new Date();

    for (i = 0; i < 999999; i++) {
        e.preventDefault();
        e.stopPropagation();
    }

    console.log( new Date() - start );

});

The above logged ~9.5 seconds as is, and ~2.5 seconds when I took the function calls out of the loop.

Upvotes: 7

Views: 939

Answers (3)

zloctb
zloctb

Reputation: 11194

<div id="wrapper">
            <div id="header">header
              <div id="footer">footer
              <div id="content">click this!!!</div>
              </div>
            </div>


        </div>


$("#wrapper div").click(function(){
  console.log(  $(this) )
});

Please try clicked to div and show console...

And now added

$("#wrapper div").click(function(e){
  e.stopPropagation()
})

Upvotes: 0

Timoth&#233;e Groleau
Timoth&#233;e Groleau

Reputation: 1960

I don't do the same thing as your colleague (pushing the 2 calls on EVERY event handler), but I do have the same practice of using these calls explicitely rather than a "return false;", and I believe that has made my life easier.

When I started with Jquery, I figured if I need to both stop propagation, and prevent default, I should just "return false", which I kind of did all over the place.

$('a.whatever').on('click', function(e) {

    do_stuff();

    return false;
}); 

But there was 2 problems I enventually encountered:

  • if do_stuff() has any critical error causing an exception, "return false;" will never be reached!!! The error will eventually be "nicely" swallowed by jquery; your event will bubble, and let the browser execute the default action. If you are in a single page app and a link was clicked, for all you know the page navigated away, and the entire app state went down the toilet (I've been there before).

  • I was too lenient with my return false: in many cases, I just needed a preventdefault(). "return false" was killing event bubbling and sometimes hindered my ability to perform another action higher up the dom hierarchy (or made some other plugin/libs I was using not work properly)

So I now prefer to be explicit. I litterally never use "return false;" any more. If I have an event handler that must either not propagate or not execute default, I deliberatly put that in my function FIRST, before any processing code. Whatever happens during event handling should NOT affect the fact that I do NOT want the default action to run, and/or event to not bubble.

And yes, that being said, I am also mindful of using just one of the 2 when required (or none at all in some cases). I do not just add both preventDefault() and stopPropagation() for no reason. Everywhere I manipulate an event in a handler, it is part of a conscious case-by-case decision.

Upvotes: 9

Kernel James
Kernel James

Reputation: 4074

It would be a problem if the element is part of a menu and the click event was supposed to bubble out and tell the menu to close itself too.

Or if a menu was open elsewhere and clicking outside the menu was supposed to bubble up to the body where an event handler would close the menu. But the element having stopped the bubble, prevents the menu from closing.

Upvotes: 0

Related Questions