Lets say I have a web app which has a page that may contain 4 script blocks - the script I write may be found in one of those blocks, but I do not know which one, that is ha
If order is important you can create your own events and bind callbacks to fire when those events are triggered by other callbacks.
$('#mydiv').click(function(e) {
// maniplate #mydiv ...
$('#mydiv').trigger('mydiv-manipulated');
});
$('#mydiv').bind('mydiv-manipulated', function(e) {
// do more stuff now that #mydiv has been manipulated
return;
});
Something like that at least.
function bindFirst(owner, event, handler) {
owner.unbind(event, handler);
owner.bind(event, handler);
var events = owner.data('events')[event];
events.unshift(events.pop());
owner.data('events')[event] = events;
}
JQuery 1.5 introduces promises, and here's the simplest implementation I've seen to control order of execution. Full documentation at http://api.jquery.com/jquery.when/
$.when( $('#myDiv').css('background-color', 'red') )
.then( alert('hi!') )
.then( myClickFunction( $('#myID') ) )
.then( myThingToRunAfterClick() );
Please note that in the jQuery universe this must be implemented differently as of version 1.8. The following release note is from the jQuery blog:
.data(“events”): jQuery stores its event-related data in a data object named (wait for it) events on each element. This is an internal data structure so in 1.8 this will be removed from the user data name space so it won’t conflict with items of the same name. jQuery’s event data can still be accessed via jQuery._data(element, "events")
We do have complete control of the order in which the handlers will execute in the jQuery universe. Ricoo points this out above. Doesn't look like his answer earned him a lot of love, but this technique is very handy. Consider, for example, any time you need to execute your own handler prior to some handler in a library widget, or you need to have the power to cancel the call to the widget's handler conditionally:
$("button").click(function(e){
if(bSomeConditional)
e.stopImmediatePropagation();//Don't execute the widget's handler
}).each(function () {
var aClickListeners = $._data(this, "events").click;
aClickListeners.reverse();
});
Dowski's method is good if all of your callbacks are always going to be present and you are happy with them being dependant on each other.
If you want the callbacks to be independent of each other, though, you could be to take advantage of bubbling and attach subsequent events as delegates to parent elements. The handlers on a parent elements will be triggered after the handlers on the element, continuing right up to the document. This is quite good as you can use event.stopPropagation()
, event.preventDefault()
, etc to skip handlers and cancel or un-cancel the action.
$( '#mybutton' ).click( function(e) {
// Do stuff first
} );
$( '#mybutton' ).click( function(e) {
// Do other stuff first
} );
$( document ).delegate( '#mybutton', 'click', function(e) {
// Do stuff last
} );
Or, if you don't like this, you could use Nick Leaches bindLast plugin to force an event to be bound last: https://github.com/nickyleach/jQuery.bindLast.
Or, if you are using jQuery 1.5, you could also potentially do something clever with the new Deferred object.
just bind handler normally and then run:
element.data('events').action.reverse();
so for example:
$('#mydiv').data('events').click.reverse();