#399 closed bug (worksforme)
Second handler firing after first returned false
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | major | Milestone: | 1.1a |
Component: | core | Version: | 1.1a |
Keywords: | event stop | Cc: | |
Blocked by: | Blocking: |
Description
When registering two functions to an event on the same element and the first executed function returns false, jQuery stops the propagation of the event, but it should also stop executing the second registered function on that event.
Example:
$('a.test').click(function(){ return false; }); $('a.test').click(function(){ alert("This shouldn't show!"); });
This can be achieved easily by placing a "break" statement in the jQuery.event.handle function.
Change History (6)
comment:1 Changed 16 years ago by
Milestone: | → 1.1 |
---|---|
Version: | 1.0 → 1.1 |
comment:2 Changed 16 years ago by
comment:3 Changed 16 years ago by
could be an option, maybe called break
even if I do not totally control the page, I have practically exclusive control on my elements, the ones that I'm adding/handling, so if I need to register more than one handler on the same event on the same elements and the first decides that the chain is to be broken, then if there is no option I have to find a workarond, but I can see that soon it gets dirty and complicated; on the contary a break option lets me get the most out of the event handling engine of jQuery
in a shared environment, I mean if there could be handlers registered by others on that same event on those same elements, the option could make use of an id, rather than a boolean, defined when binding and referenced when triggering, like this
$( ".aClass" ).bind( "click", fn1, {break: "myID1"} );
code I don't control...
$( ".aClass" ).bind( "click", fn2, {break: "myID2"} );
$( ".aClass" ).bind( "click", fn3 );
code I do control...
$( ".aClass" ).bind( "click", fn4, {break: "myID1"} );
$( ".aClass" ).trigger( "click", {break: "myID1"} );
which would mean that if fn1 returns false, then fn4 is not to be called, but fn2 and fn3 would not be influenced by the result of fn1
the default for bind should be undefined and for trigger {break: false}, which means "any false event won't break propagation"
and could exist the opposite for trigger {break: true}, which means "the first false event will break propagation"
comment:4 Changed 16 years ago by
avaly2k, what was the scenario in your code where delivering the second click broke something? Maybe the goal can be accomplished in some other way.
Right now, the jQuery handler calls all the handlers and remembers whether any returned false. If one or more did, the jQuery handler returns false. If you had two submit or change handlers, for example, that seems like the right behavior. Perhaps all it needs is to be documented to work that way?
A page with plugins and page-specific jQuery code could have multiple handlers of the same type attached to an element. Handlers can be attached while the page is in use; attempting to control the initialization order in a .ready() handler is futile. No handler can reliably be the first called, return false, and shut out the others.
comment:5 Changed 16 years ago by
If you add your events via addEventListener, I'm quite sure that it behaves like actual jQuery, so it continues with the second event. I think it's very important to strictly seperate these events in functionality, so one event cannot stop another.
comment:6 Changed 16 years ago by
Resolution: | → worksforme |
---|---|
Status: | new → closed |
I agree with Paul: The behaviour of calling events should stick to the one of addEventListener.
It should be possible to workaround this feature by using an external context:
var allowOthers = true; $('a.test').click(function(){ allowOthers = false; }); $('a.test').click(function(){ if(allowOthers) alert("This shouldn't show!"); });
With jQuery 1.1 it's possible to avoid that external context, eg.:
var data = { allowOthers: true }; $('a.test').click(function(event, data){ data.allowOthers = false; }, data ); $('a.test').click(function(event, data){ if(data.allowOthers) alert("This shouldn't show!"); }, data );
I disagree. Two points:
Situations where this behaviour is needed are the exceptions not the rule.