gpt4 book ai didi

javascript - 阐明 IE 中的 clearTimeout 行为

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:06:45 25 4
gpt4 key购买 nike

我有以下代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<div id="logger"></div>
<script>

function log(txt) {
document.getElementById('logger').innerHTML += txt + '<br>';
}

var int = 10;
var a= setTimeout(function(){
a = null;
log("A fired!");
clearTimeout(b);
b = null;
}, int);

var b = setTimeout(function(){
b = null;
log("B fired!");
clearTimeout(a);
a = null;
}, int);


</script>

</body>
</html>

两个超时回调都应该防止另一个另一个触发。在 Opera、FF 和 Chrome 中只执行第一个(打印“A fired”)。但是当我在 IE6 和 IE8 中运行相同的代码时,两个回调都会被执行。这是我的脚本中的某些错误还是这些浏览器充满的错误之一? clearTimeout()/clearInterval() 是否保证调用后不会调用回调?

最佳答案

我认为发生的事情是:

  • JavaScript 有一个事件队列。
  • IE 处理超时,并对两个事件进行排队。
  • 处理了第一个超时事件,并为 B 调用了 clearTimeout。但是 B 的事件已经排队,所以它仍然被触发。
  • 处理完第二个超时事件,为A调用clearTimeout。

我怀疑在 IE 中,事件被排队并且调用 clearTimeout 不会从事件队列中删除事件。

也有可能 IE 将同时超时推送到队列的方式很古怪...诊断根本原因可以通过使用两个不同的超时、使用 100% CPU 处理循环 x 时间以及通过排队/插入其他事件(也许可以使用 window.postMessage() 将事件注入(inject)队列并使用 window.onMessage() 捕获它们)。

我修改了您现有的代码以更好地演示问题。它对日志项进行排队而不是立即执行它们,因为调用 display() 会导致布局或渲染发生,这很容易引入其他时髦的干扰。

编辑:您可以使用 http://jsbin.com/ucukez/2 进行测试- 如果浏览器出现故障,那么您会得到“在 A 超时中被触发”“在 B 超时中被触发”。

编辑:这已在 IE9 中修复 - 我无法在 IE9/IE10/IE11 中重现。

HTML 是:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>setTimeout queued test</title>
<script>
function display(txt) {
document.getElementById('logger').innerHTML += txt + '<br>';
}

var log = {
items: [],
push: function(text) {
this.items.push(text);
},
display: function() {
var items = this.items;
this.items = [];
for (var i = 0; i < items.length; i++) {
display(items[i]);
}
}
};

function startTest() {
var ms = 10;

display("startTest()");
log.push('before A setTimeout');
var a = setTimeout(function(){
log.push('in A timeout fired');
display("A fired!");
log.push('in A clear timer B');
clearTimeout(b);
log.push('in A cleared timer B');
}, ms);
log.push('after A setTimeout');

log.push('before B setTimeout');
var b = setTimeout(function(){
log.push('in B timeout fired');
display("B fired!");
log.push('in B clear timer A');
clearTimeout(a);
log.push('in B cleared timer A');
}, ms);
log.push('after B setTimeout');

setTimeout(function(){
display("");
display("Displaying logged items:");
log.display();
},1000);
}
</script>
</head>
<body onload="startTest()">
<div id="logger"></div>
</body>
</html>

关于javascript - 阐明 IE 中的 clearTimeout 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5853571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com