Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run code after all other events have been handled

Tags:

jquery

I have an event handler, but I want to make sure that it will wait until all the other events in the event queue have executed.

For example, I have some tabs on a page. I have some general code for handling tabs that sets a tab to "Active Tab" when a user clicks on it.

$('a.tab').click(function() {   $(this).parent('div').find('a.tab').removeClass('activeTab');   $(this).addClass('activeTab'); }); 

For a specific set of tabs, I might have a handler:

// handler-1 $('div#myTabs a.tab').click(function() {   do_something(); });  function do_something() {   var type = $('div#myTabs a.activeTab').data('type');   do_something_else(type); } 

do_something() might get called in response to other actions besides clicking on a tab, but regardless of how it gets invoked, it wants to know what the active tab is before it can continue.

My problem is that if it is getting invoked by the code under '// handler-1', the class 'activeTab' may not have been reset yet, so the value it retrieves for 'type' will still be from whatever tag was selected prior to clicking on this one.

I solved it like this:

// handler-1 $('div#myTabs a.tab').click(function() {   set_timeout( function() {     do_something();   }, 100); }); 

This looks like too much of a kludge to satisfy me. How do I know that the timer event handler will get called only after all the other handlers have had their turn? Sure I could change "100" to "1000" or even "10000" but I would also be trading performance for more certainty (and there is still no certainty since even 10 seconds may not be enough on a browser instance on a machine that is crippled enough).

I have seen several possible solutions:

  • How to order events bound with jQuery
  • Binding multiple events in jQuery

but neither of these are general enough to satisfy me. I'm not trying to get a handler to run first. Rather, I want something like this:

function do_something() {   $.when_all_other_events_have_been_handled(function() {     do_something();   }); }); 

Does anything like this exist?

I looked at $.fn.when(arg).done(), but when what? "arg" in this case would have to be a deferred object that executes whatever is already in the run queue. A Catch-22!

Sproutcore has something like "engine.run()" (don't remember the exact name) that will return only when all other events in the "engine" have been handled, but I can't find anything like that in jQuery. (http://api.jquery.com/category/events/). If anyone knows of something like that, please let me know!

Thanks! :)

like image 633
Lawrence I. Siden Avatar asked Oct 13 '11 21:10

Lawrence I. Siden


People also ask

What are three ways to use events in your code?

There are three ways to declare an event in JavaScript: inline, using a property, or using a listener.


1 Answers

Try this:

function postpone( fun ) {   window.setTimeout(fun,0); } 

so if you will call postpone(do_something); that do_something will be executed after all UI events that are in the event queue for the moment of postpone() call.

like image 87
c-smile Avatar answered Sep 19 '22 04:09

c-smile