为什么我的脚本JS的事件处理程序
我已经阅读了以下主题is-javascript-guaranteed-to-be-single-threaded 打断还有就是很好的例子有:为什么我的脚本JS的事件处理程序
<textarea id="log" rows="20" cols="40"></textarea>
<input id="inp">
<script type="text/javascript">
var l= document.getElementById('log');
var i= document.getElementById('inp');
i.onblur= function() {
l.value+= 'blur\n';
};
setTimeout(function() {
l.value+= 'log in\n';
l.focus();
l.value+= 'log out\n';
}, 100);
i.focus();
</script>
输出是
log in
blur
log out
,而不是预期的
log in
log out
blur
所以这基本上显示我的事件处理程序blur
被触发,这会中断setTimeout回调内代码的执行。我读过几篇文章和解释,说明代码不会被打断(run-to-completion principle),除了一些角落案例,如模式弹出窗口(警报,提示窗口)。那么为什么在这个例子中被打断?
我唯一可以解释的是我从代码手动触发focus
事件,同时控制执行是在JS引擎上。如果不是手动触发,代码执行期间的模糊事件将被浏览器检测到并放入队列中,只有在代码执行完成后(堆栈为空),队列才会被处理。
正如问题说明你链接到:
在上面的例子中,重点是:
浏览器会在您的代码做一些事情,使他们解雇这些[赛事]马上一个元素会导致先前拥有焦点的元素上的立即
blur
事件。此事件没有排队,它立即触发。实际上,focus()
方法直接调用以前为焦点的元素的blur
侦听器。立即执行此操作很有用,以便
blur
处理程序可以确保能够访问剩余元素的当前状态;我们不想让其他代码有机会首先更改字段。
谢谢!但是,我提到的解决即时事件的概念,即未添加到队列中的事件的答案呢?你是否知道任何其他来源可以阅读有关未添加到队列中的事件? – 2014-09-11 10:17:24
我在那里发表了一个关于它的问题。如果您对答案有疑问,那就应该这样做,而不是发布一个新问题。 – Barmar 2014-09-11 10:19:03
我明白了,谢谢。我只是认为在评论中讨论内容并不是一件好事。我会在那里关注你的评论。 – 2014-09-11 10:26:10
这是不是解释了你从代码复制的答案? – Barmar 2014-09-11 09:48:44
嗯,这个问题的答案是,作者将这个例子与模态弹出窗口混合在一起'这些事件不仅仅是因为你直接调用了focus(),而是因为你调用了alert()或者打开了一个pop-窗口或其他任何可以移动焦点的窗口。然后他的大部分答案都与模态弹出窗口有关。然而,第一个例子和模式弹出窗口非常不同。 – 2014-09-11 09:53:08
他在代码的上方解释了它:_Browsers会在你的代码执行某些操作时立即触发这些代码:_ – Barmar 2014-09-11 09:54:49