我已经在一些编码上使用了setTimeout几天,它在我的主要测试浏览器Chrome上工作。一旦我在不同的浏览器上检查了该功能,Internet Explorer就给了我一个问题,根本没用。其他浏览器也有效。
$(childWindow).load(function()
{
var dateObject = new Date();
var startTime = Date.now() + (dateObject.getTimezoneOffset() - 300) * 60000; // GMT -5
var currentTime = startTime();
var counter = 0;
var runningFunction = function()
{
var remainingTime = Math.round((startTime + 10 * 1000 - (Date.now() + (dateObject.getTimezoneOffset() - 300) * 60000)) / 1000);
if (remainingTime > 0)
{
// update timer in HTML which is not shown
currentTime = Date.now() + (dateObject.getTimezoneOffset() - 300) * 60000;
var nextCounter = 100 - (currentTime - (startTime + (counter * 100))); // compensate for browser drifting
counter++;
childWindow.setTimeout(runningFunction, nextCounter); // try to update nearly at 100 milliseconds every 100 milliseconds
}
};
childWindow.setTimeout(runningFunction, 100); // initially update at 100 milliseconds
// other jQuery coding used
});
这只是代码的一部分,但我认为问题所在。某些逻辑或语法可能不正确,但这不是我遇到的问题。 10秒后,不应该有一个setTimeout调用,因为remainingTime是负数,所以确实没有“无限循环”。使用这个(部分)代码,它可以在Chrome中完美运行并且每100毫秒执行一次。在Internet Explorer中,根本没有任何事情发生。我读了其他Stack Overflow帖子和其他外部资源,语法应该是setTimeout(function() { calleeFunction(); }, time);
我尝试将var runningFunction = function()
更改为function runningFunction()
,将setTimeout
功能部分更改为function() { runningFunction(); }
,该功能可以正常工作,但在Chrome和Internet Explorer中完全挂起,最终导致一些堆栈错误(在10秒“无限”setTimeout
调用循环期间,我认为这是IE中的脚本28。
我尝试的另一个解决方案是var runningFunction = (function() { ... }());
但是此行在childWindow.setTimeout(runningFunction, 100);
行之前执行。我希望变量只是声明但在执行childWindow.setTimeout
行之前不会执行。我不介意将匿名函数放在setTimeout
函数中,但我实际上在程序的其他部分使用这个确切的行来重新启动计时器,函数本身超过200行,所以我不会我想在程序的多个部分复制相同的200行。
基于Oriol的响应/更新的代码
$(childWindow).load(function()
{
$.post("x.php", { a: "", b: "", c: "" }, function(data)
{
if (data !== "")
$("div:first", childWindow.document).html(data);
else
{
var dateObject = new Date(),
startTime = aux(),
currentTime,
counter = 0;
function aux() {
return +new Date() + (dateObject.getTimezoneOffset() - 300) * 6e4;
}
function runningFunction()
{
console.log('runningFunction');
var currentAux = aux(),
remainingTime = Math.round( 10 + (startTime - currentAux) / 1e3 );
if (remainingTime > 0)
{
$("div:first", childWindow.document).html("<div>" + remainingTime + "</div>");
currentTime = currentAux;
var nextCounter = Math.max(0, 100 - currentTime + startTime + counter * 100);
// compensate for browser drifting
counter++;
childWindow.setTimeout(runningFunction, nextCounter);
// try to update nearly at 100 milliseconds every 100 milliseconds
}
}
$("div:first", childWindow.document).html("<div>Random message.</div>");
if (childWindow.document.hasFocus() && childWindow.outerWidth >= 0.90 * screen.availWidth && childWindow.outerHeight >= 0.90 * screen.availHeight)
{
var pauseTime = "";
var running = true;
childWindow.setTimeout(runningFunction, 100);
}
else
{
var pauseTime = startTime;
var running = false;
}
}
});
});
提供的小提琴确实有效,但它在网站上不起作用。基于此编码,setTimeout
无法执行的唯一方法是最后一个if语句块是否为false。我在true语句中放了一个console.log消息,它确实返回了该消息,因此我知道IE正在执行该块,因此它必须到达setTimeout
行。再次,使用此编码,出现与最初发布时相同的情况,Chrome每隔约100毫秒在函数中显示console.log消息,IE甚至根本不考虑该功能。我真的跑到了死胡同。
答案 0 :(得分:0)
您的代码存在一些问题:
Date.now()
支持。您可以使用+new Date()
nextCounter
为负数,因此延迟函数不会在IE上运行。您可以使用Math.max(0, nextCounter)
。这有效:
var dateObject = new Date(),
startTime = aux(),
currentTime,
counter = 0;
function aux() {
return +new Date() + (dateObject.getTimezoneOffset() - 300) * 6e4;
}
function runningFunction()
{
console.log('runningFunction');
var currentAux = aux(),
remainingTime = Math.round( 10 + (startTime - currentAux) / 1e3 );
if (remainingTime > 0)
{
// update timer in HTML which is not shown
currentTime = currentAux;
var nextCounter = Math.max(0, 100 - currentTime + startTime + counter * 100);
// compensate for browser drifting
counter++;
childWindow.setTimeout(runningFunction, nextCounter);
// try to update nearly at 100 milliseconds every 100 milliseconds
}
};
childWindow.setTimeout(runningFunction, 100);
// initially update at 100 milliseconds