为什么我的脚本在JS中被事件处理程序中断

时间:2014-09-11 09:36:23

标签: javascript

我已阅读以下主题is-javascript-guaranteed-to-be-single-threaded 那里有一个很好的例子:

<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引擎上。如果没有手动触发,则执行代码期间的模糊事件将被浏览器检测到并放入队列中,只有在代码执行完成后(堆栈为空)才会处理该队列。

1 个答案:

答案 0 :(得分:1)

如您所链接的问题所述:

  

当代码执行某些操作时,浏览器会立即触发这些[事件]:

在上面的示例中,关注元素会导致以前具有焦点的元素发生立即blur事件。此事件未排队,它会立即触发。实际上,focus()方法直接调用以前关注元素的blur侦听器。

立即执行此操作非常有用,这样blur处理程序可以确保可以访问剩余元素的当前状态;我们不想让其他代码有机会先改变字段。