本文共 1169 字,大约阅读时间需要 3 分钟。
汉游天下掼蛋源码里原文中有这么一段话,描述的有点抽象:
JavaScript引擎在执行onmousedown时,由于没有多线程的同步执行,不可能同时去处理刚创建元素的focus 和select方法,由于这两个方法都不在队列中,在完成onmousedown后,JavaScript 引擎已经丢弃了这两个任务,正如第一种情况。而在第二种情况中,由于setTimeout可以把任务从某个队列中跳脱成为新队列,因而能够得到期望的结果。我看到这里就觉得非常不对劲了。因为按照这种任务会被丢弃的说法,那么只要在事件触发的函数中再触发其他的事件都会被丢弃,浏览器是绝对不会这么做的,于是我编写了测试代码:
http://vdisk.weibo.com/s/FuhRYFUVntpTa
window.onload = function () { //第一个例子:未使用setTimeout get('makeinput').onmousedown = function () { var input = document.createElement('input'); input.setAttribute('type', 'text'); input.setAttribute('value', 'test1'); get('inpwrapper').appendChild(input); //按照文中的理论,这里的click不会被触发,但它却成功触发了 get('inpwrapper').click();//触发了inpwrapper的onclick事件 } get('inpwrapper').onclick = function () { alert('linkFly'); }; }下面的onclick()最终是执行了:弹出了"linkFly"。
而在转载的文中为了引人深思,又提出了第三个例子:
在此,你可以看看例子 3,它的任务是实时更新输入的文本,现在请试试,你会发现预览区域总是落后一拍,比如你输 a, 预览区并没有出现 a, 在紧接输入b时,a才不慌不忙地出现。而文中最后留给大家的思考的问题,解决方案就是使用setTimeout再次调整浏览器的代码任务运行队列。
var domInput = get('input'); domInput.onkeypress = function () { setTimeout(function () { //第三个例子的问题就这样就会被解决 get('preview').innerHTML = domInput.value; }) }原文和转载的文章中都对setTimeout(fn,0)进行了思考,但原文指出的问题本质漏洞百出,所以才出了这篇文章,我们的正文,现在开始。