Why does returning false stop propagation with jQuery while it doesn't with POJS?

javascript, jquery

Solution

On line 3331 of version 1.7.1, in `jQuery.event.dispatch`:

ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
         .apply( matched.elem, args );

if ( ret !== undefined ) {
    event.result = ret;
    if ( ret === false ) {
        event.preventDefault();
        event.stopPropagation();
    }
}

A lot of packaging has happened before this line, but basically, it runs the handler function (either a raw function, or the `handler` memeber function of a `handlerObject`) using `apply`. If the result of that call is false, it does `preventDefault` and `stopPropagation`.

This is mentioned in the documentation for `on()`:

Returning `false` from an event handler will automatically call `event.stopPropagation()` and `event.preventDefault()`.

As for why they did it? I don't know, as I'm not not the jQuery design team, but I assume it's just because `return false` is a lot quicker to type than `event.preventDefault(); event.stopPropagation();`. (And if jQuery isn't about making sure you have less to type, I'm not sure what it's about.)

I don't believe the return value of an event handler is ever actually used anywhere in POJS (someone correct if that's wrong!). Thus, jQuery can safely have a `return` statement cause side effects in a handler (since returning false in a POJS handler is meaningless, no POJS functionality is harmed).

Problem

Here is a jsfiddle using POJS showing that `return false;` doesn't stop the event's propagation: http://jsfiddle.net/Ralt/Lz2Pw/ Here is another using jQuery showing that `return false;` does stop the event's propagation: http://jsfiddle.net/Ralt/D5Mtg/ Edit: The one explaining to me why jQuery does this - differing from the original behavior intentionally - (and where in the code) gets the answer. Here is the code (long, but very easy to read): HTML for both versions: ``` <div id="parent1"> <div id="child1"><a href="#" id="a1">child1</a></div> </div> <div id="parent2"> <div id="child2"><a href="#" id="a2">child2</a></div> </div> <div id="parent3"> <div id="child3"><a href="#" id="a3">child3</a></div> </div> ``` POJS: ``` document.getElementById( 'child1' ).onclick = function( e ) { console.log( 'child1' ); e.preventDefault(); }; document.getElementById( 'parent1' ).onclick = function( e ) { console.log( 'parent1' ); }; document.getElementById( 'child2' ).onclick = function( e ) { console.log( 'child2' ); return false; }; document.getElementById( 'parent2' ).onclick = function( e ) { console.log( 'parent2' ); }; document.getElementById( 'child3' ).onclick = function( e ) { console.log( 'child3' ); e.stopPropagation(); }; document.getElementById( 'parent3' ).onclick = function( e ) { console.log( 'parent3' ); }; ``` jQuery version: ``` $( '#child1' ).click( function( e ) { console.log( 'child1' ); e.preventDefault(); }); $( '#parent1' ).click( function( e ) { console.log( 'parent1' ); }); $( '#child2' ).click( function( e ) { console.log( 'child2' ); return false; }); $( '#parent2' ).click( function( e ) { console.log( 'parent2' ); }); $( '#child3' ).click( function( e ) { console.log( 'child3' ); e.stopPropagation(); }); $( '#parent3' ).click( function( e ) { console.log( 'parent3' ); }); ```

Original source