当前位置: 首页 > 知识库问答 >
问题:

window.setTimeout窗口不在焦点时的行为[重复]

师冥夜
2023-03-14

下面是我能想到的最简单的复制代码:

ms = 30; // 1000 ?
num = 1;
function test()
{
    num+=ms;
    document.getElementById('Submit').value = num; // Using native Javascript on purpose
    if (num < 4000)
        window.setTimeout(test, ms);
}
test()

我将ms(迭代间隔毫秒)设置为30,运行脚本并移动到浏览器上的不同选项卡。

然后我等待了大约10秒钟(脚本应该在4秒钟内完成),然后返回到选项卡。

如果我使用火狐,我看到脚本还没有完成,数字还在运行(我猜是从我留下的地方恢复的)。

这已经够烦人的了,

但是如果我将ms更改为1000并重复上述步骤,当我回到选项卡时,我看到脚本确实已经完成。

(脚本仍然需要4秒钟才能完成)。

也就是说,有时Firefox会运行window.setTimeout,即使窗口没有焦点,有时也不会。可能取决于持续时间

另一方面,Internet Explorer不会出现这种情况。

即使选项卡没有聚焦,它也会继续运行脚本。无论我如何设置ms

>

到底发生了什么?

为什么现在浏览器之间如此基本的东西是一致的?

或者,我做错了吗?这是一种奇怪的编码方式吗?

我只是尝试以延迟的方式重复更改DOM,而不使用setInterval(因为我正在更改它自己的时间间隔)。

  • 最重要的是,我应该如何看待这一点

我不能假设我的用户不会离开该选项卡。

我想让我的用户离开这个页面,尽可能多地浏览。

如果一个人在半小时后离开并回来,他/她将在页面上看到不相关的动画,仍然在运行。

连接到页面的所有用户都可以看到其中一些动画。

没有必要将它们以毫秒的分辨率同步,但是我不能仅在用户将选项卡/窗口聚焦时启动它们。

我正在使用Firefox25.0.1和IE11。(Windows 7)

共有3个答案

归浩博
2023-03-14

setTimeout不是精确的计时。因为计时器不会中断进程,所以我会等待空闲时间。我不知道浏览器是如何管理它的,但是一个不活动的选项卡可能具有较低的优先级。

我可以考虑两种解决方案:-尝试setInterval(我不确定这是否能解决您的问题)-不要增加变量,而是使用日期对象,在开始时包含时间,并将其与执行函数时的当前时间进行比较。

var beginTime = (new Date()).getTime();
var intervalId = setInterval(function() {
    var timePassed = (new Date()).getTime() - beginTime;
    document.getElementById('Submit').value = timePassed;
    if(timePassed >= 4000) {
        clearInterval(intervalId);
    }
}, 30);
武卓
2023-03-14

请看区别:http://jsfiddle.net/qN6eB/

ms = 30; // 1000 ?
num = 1;
start = new Date();

function test()
{
    num+=ms;
    document.getElementById('Submit').value = num;
    if (num < 4000)
        window.setTimeout(test, ms);
    else
        document.getElementById('Time').value = new Date() - start;
}

test()



ms2 = 30; // 1000 ?
num2 = 1;
start2 = new Date();
dueTo = new Date(+new Date()+4000);

function test2()
{
    num2+=ms2;
    document.getElementById('Submit2').value = num2;
    if (new Date() < dueTo)
        window.setTimeout(test2, ms2);
    else 
        document.getElementById('Time2').value = new Date() - start2;
}
test2()
邵羽
2023-03-14

大多数现代浏览器(尤其是移动设备上的浏览器)都会暂停对焦点不集中的选项卡中的脚本的执行,以节省CPU周期(例如,这就是为什么requestAnimationFrame出现的原因)。在超时的情况下,更短的间隔实际上会根据浏览器供应商认为合适的情况更改为不同/更高的值。

要克服这一点(如果您确实必须知道连续执行之间的间隔),可以在激活超时时设置时间戳,并将其与实际执行超时处理程序时的时间戳进行比较。请注意,在设置动画时,最好通过考虑其他应用程序变量来计算动画对象的属性,而不是依赖于特定处理程序的调用量。

您还可以将侦听器附加到“(un)focus”事件的窗口,以了解用户何时“返回”到您的应用程序。在这个事件处理程序中,您可以验证超时是否处于挂起状态,并手动执行其回调(如果必须这样做的话)。

 类似资料:
  • 我有一个tkinter python 2。x程序。我有几个窗口出现在屏幕上。我用按钮从一个窗口导航到另一个窗口,但我很难关闭一个窗口并重新关注当前打开的窗口。我可以很好地打开新窗口!

  • 卡洛斯·巴罗斯 编辑:也许我应该这么说,但这个游戏是一个类似反击或英雄联盟的游戏,我没有做这个游戏。

  • 在嵌入式框架内使用JComboBox时,我确实有一个奇怪的焦点问题。 我创建了一个新的Shell 我用来创建嵌入式框架的外壳,如 我添加了一个JComboBox(有2个元素)到rootGroup。当我选择ComboBox打开下拉菜单时,我可以拖放shell窗口,而不会丢失组合框中的焦点。 当外壳窗口移动到另一个屏幕区域时,下拉菜单仍然在屏幕上的同一位置。下拉菜单不再显示在组合框下面。 我试图为某些

  • 问题内容: 我的项目包括Selenium Webdriver,JAVA,Maven,TestNG,Jenkins,Allure(报告)。我有几套包含100多个测试用例的测试,并通过3种不同的浏览器进行了迭代(测试使用TestNG并行运行)。 除非我实际上正在观察窗口并查看测试运行,否则无法通过一项测试。 我将解释: 我要测试什么? 我们的JS开发人员创建了一项功能,仅当用户将焦点放在窗口上时,图像

  • 有没有可能让下拉菜单的选择窗口使用css中的焦点标记,但下拉菜单中的实际元素不使用该焦点标记?我现在使用选项:checked标记,但这只会更改选定的项目。这是我的代码:

  • 我正在用Tkinter编写一个小程序,想打开两个窗口。然后我想在前面放一扇窗户。程序代码: 我做错了什么new.lift?新密码没有出现在前面:(有人知道如何把窗口放在前面,让窗口聚焦吗?