javascript - Varför stoppar return false spridning med jQuery medan det inte gör det med POJS?
Här är en jsfiddle som använder POJS som visar att return false; inte stoppar händelsens spridning: http://jsfiddle.net/Ralt/Lz2Pw/
Här är ett annat exempel som använder jQuery och visar att return false; faktiskt stoppar händelsens spridning: http://jsfiddle.net/Ralt/D5Mtg/
Redigera: Den som förklarar för mig varför jQuery gör detta - avsiktligt annorlunda än det ursprungliga beteendet - (och var i koden) får svaret.
Här är koden (lång, men mycket lätt att läsa):
HTML för båda versionerna:
<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' ); });
Svar #1
På rad 3331 i version 1.7.1, i 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();
}
}
Mycket paketering har hänt innan denna rad, men i princip kör den hanteringsfunktionen (antingen en vanlig funktion, eller handler-medlemsfunktionen av ett handlerObject) med apply. Om resultatet av det anropet är false, gör den preventDefault och stopPropagation.
Detta nämns i dokumentationen för on():
Att returnera
falsefrån en eventhanterare kommer automatiskt att kalla påevent.stopPropagation()ochevent.preventDefault().
När det gäller varför de gjorde det? Jag vet inte, eftersom jag inte är jQuerys designteam, men jag antar att det helt enkelt är för att return false är mycket snabbare att skriva än event.preventDefault(); event.stopPropagation();. (Och om jQuery inte handlar om att se till att du har mindre att skriva, vet jag inte vad det handlar om.)
Jag tror inte att returvärdet från en eventhanterare någonsin faktiskt används någonstans i POJS (någon får korrigera om det är fel!). Därför kan jQuery säkert ha ett return-uttryck som orsakar bieffekter i en hanterare (eftersom att returnera false i en POJS-hanterare är meningslöst, påverkas ingen POJS-funktionalitet).
