我最近遇到了一个相当讨厌的错误,其中代码正在加载一个<select>
通过 JavaScript 动态地。这个动态加载的<select>
有一个预先选定的值。在 IE6 中,我们已经有代码来修复所选的<option>
,因为有时<select>
's selectedIndex
值将与所选的不同步<option>
's index
属性,如下:
field.selectedIndex = element.index;
但是,这段代码不起作用。尽管该领域的selectedIndex
如果设置正确,最终会选择错误的索引。但是,如果我卡住了alert()
在正确的时间陈述,就会选择正确的选项。认为这可能是某种计时问题,我尝试了一些我之前在代码中看到的随机内容:
var wrapFn = (function() {
var myField = field;
var myElement = element;
return function() {
myField.selectedIndex = myElement.index;
}
})();
setTimeout(wrapFn, 0);
这成功了!
我已经找到了解决问题的方法,但我很不安,因为我不知道为什么这可以解决我的问题。有谁有官方的解释吗?我通过“稍后”调用我的函数来避免什么浏览器问题setTimeout()
?
问题中存在一个竞争条件之间:
- 浏览器尝试初始化下拉列表,准备更新其选定的索引,并且
- 用于设置所选索引的代码
您的代码始终赢得这场比赛,并尝试在浏览器准备就绪之前设置下拉选择,这意味着会出现错误。
这场竞赛的存在是因为 JavaScript 有一个单线程执行与页面渲染共享。实际上,运行 JavaScript 会阻止 DOM 的更新。
您的解决方法是:
setTimeout(callback, 0)
调用setTimeout
带有回调,并且第二个参数为零将安排回调运行异步地,在尽可能短的延迟之后 - 当选项卡具有焦点并且 JavaScript 执行线程不忙时,延迟时间约为 10 毫秒。
因此,OP 的解决方案是将所选索引的设置延迟大约 10 毫秒。这给了浏览器一个初始化 DOM 的机会,修复了 bug。
每个版本的 Internet Explorer 都表现出奇怪的行为,有时这种解决方法是必要的。或者,它可能是 OP 代码库中的一个真正的错误。
参见菲利普·罗伯茨的演讲“事件循环到底是什么?”以获得更彻底的解释。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)