Side navigation
#399 closed bug (worksforme)
Opened November 16, 2006 03:28PM UTC
Closed December 02, 2006 01:14PM UTC
Last modified June 19, 2007 07:00AM UTC
Second handler firing after first returned false
Reported by: | avaly2k@hotmail.com | 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.
Attachments (0)
Change History (6)
Changed November 17, 2006 08:02PM UTC by comment:1
milestone: | → 1.1 |
---|---|
version: | 1.0 → 1.1 |
Changed November 29, 2006 10:52PM UTC by comment:2
Changed November 30, 2006 02:05AM UTC by comment:3
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"
Changed November 30, 2006 04:00AM UTC by comment:4
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.
Changed November 30, 2006 07:57AM UTC by comment:5
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.
Changed December 02, 2006 01:14PM UTC by comment:6
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.