jQuery 如何在处理完所有其他事件后运行代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7760428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run code after all other events have been handled
提问by Lawrence I. Siden
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.
do_something() 可能会被调用以响应除单击选项卡之外的其他操作,但无论它是如何调用的,它都想在继续之前知道活动选项卡是什么。
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.
我的问题是,如果它被 '// handler-1' 下的代码调用,则类 'activeTab' 可能尚未重置,因此它为 'type' 检索的值仍将来自选择的任何标记在点击这个之前。
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).
这看起来太多了,无法满足我。我怎么知道计时器事件处理程序只有在所有其他处理程序轮到他们之后才会被调用?当然,我可以将“100”更改为“1000”甚至“10000”,但我也会为了更多的确定性而交易性能(并且仍然不确定,因为在机器上的浏览器实例上,即使 10 秒也可能不够)够残废)。
I have seen several possible solutions:
我已经看到了几种可能的解决方案:
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!
我看着 $.fn.when(arg).done(),但是什么时候呢?在这种情况下,“arg”必须是一个延迟对象,它执行运行队列中已经存在的任何内容。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!
Sproutcore 有类似“engine.run()”(不记得确切名称)之类的东西,只有在“引擎”中的所有其他事件都被处理后才会返回,但我在 jQuery 中找不到类似的东西。(http://api.jquery.com/category/events/)。如果有人知道这样的事情,请告诉我!
Thanks! :)
谢谢!:)
回答by c-smile
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.
所以,如果你会叫postpone(do_something);
那do_something
将是在瞬间的事件队列中的所有UI事件后执行postpone()
的呼叫。
回答by Lawrence I. Siden
I may have found the answer here: http://ejohn.org/blog/how-javascript-timers-work/
我可能在这里找到了答案:http: //ejohn.org/blog/how-javascript-timers-work/
According to J. Resig, if I do
根据 J. Resig 的说法,如果我这样做
setTimeout(function() {
do_something();
}, 0);
the anonymous function will get enqued immediately but will not get called until everything else on the event queue has already been handled. That is, as long as whatever browser its running really runs everything on a first-in-first-out basis as I would expect it to. If for any reason the Javascript engine takes it upon itself to re-order events in the queue (I don't know why it should, but you never know since AFAIK I've never seen any such guarantee in the standards, but then I need to look again) then all bets are off!
匿名函数将立即入队,但在事件队列中的其他所有内容都已处理完毕之前不会被调用。也就是说,只要它运行的任何浏览器真的像我期望的那样以先进先出的方式运行所有内容。如果 Javascript 引擎出于任何原因自行对队列中的事件进行重新排序(我不知道为什么应该这样做,但是自从 AFAIK 以来你永远不知道我从来没有在标准中看到任何这样的保证,但是我需要再看一遍)然后所有的赌注都关闭了!