如何解决setTimeout可以通过多个选项卡加快速度
| 我遇到了与此类似的setTimeout问题。但是该解决方案对我没有帮助,因为我无法在文件中使用PHP。 我的网站上有一个滑块,其中包含每8秒移动一次的图像列表。但是,当我在浏览器中打开几个选项卡然后再次切换回时,它变得很疯狂。 滑块会立即连续移动图像,而不会延迟8秒。 我只在Chrome和最新的Firefox中看到它。 **编辑:我用console.log()检查过,并且setTimeout在clearTimeout之前和之后返回相同的数字。不知道为什么。也许这也与它有关? ** 编辑2:我添加了一个小提琴:http://jsfiddle.net/Rembrand/qHGAq/8/ 该代码如下所示:spotlight: {
i: 0,timeOutSpotlight: null,init: function()
{
$(\'#spotlight .controls a\').click(function(e) {
// do stuff here to count and move images
// Don\'t follow the link
e.preventDefault();
// Clear timeout
clearTimeout(spotlight.timeOutSpotlight);
// Some stuff here to calculate next item
// Call next spotlight in 8 seconds
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.animate(spotlight.i);
},8000);
});
// Select first item
$(\'#spotlight .controls a.next:first\').trigger(\'click\');
},animate: function(i)
{
$(\'#spotlight .controls li:eq(\' + (spotlight.i) + \') a.next\').trigger(\'click\');
}
}
解决方法
从jQuery文档中:
由于requestAnimationFrame()的性质,您永远不应该
使用setInterval或setTimeout循环将动画排入队列。为了
保留CPU资源,支持requestAnimationFrame的浏览器
当不显示窗口/选项卡时,将不会更新动画。如果
您继续通过setInterval或setTimeout将动画排入队列,同时
动画已暂停,所有排队的动画将开始播放
当窗口/标签重新获得焦点时。为避免此潜在问题,
在循环中使用您上一个动画的回调,或附加一个
对元素.queue()的函数设置超时时间以开始下一个
动画。
,我终于找到了答案,这根本不是我所期望的。
罪魁祸首似乎是jQuery的.animate(),我用它在滑块中移动图像。
我以此计算并移动图像位置:
$(\'.spotlight-inner\')
.animate(
{ left: scrollToVal },{duration: \'slow\'}
)
;
现在的问题似乎是在某些浏览器中,当您切换到新的选项卡并返回时,jQuery的.animate()保存动画并立即将其全部触发。因此,我添加了一个过滤器以防止排队。该解决方案来自CSS-Tricks.com:
$(\'.spotlight-inner\')
.filter(\':not(:animated)\')
.animate(
{ left: scrollToVal },{duration: \'slow\'}
)
;
当您返回时看到的第一张幻灯片可能有点跳动,但它比以前的超高速旋转木马要好。
在这里摆弄完整的代码
,使用jquery animate queue属性有一种更简单的方法:
$(this).animate({
left: \'+=100\'
},{duration:500,queue:false});
,我不知道这是否对您有帮助,但是幻灯片显示对我有帮助。我所做的就是每次我调用一个由于setTimeout而应在固定间隔内发生的动画时,我都调用clearQueue()来清除任何其他已设置为发生的动画。然后我会调用动画。这样一来,当您返回该标签时,就不会将所有这些动画排入队列,这简直太疯狂了。最多只能设置一个。
所以像这样:
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.clearQueue(); // get rid of other instances of the animation
spotlight.animate(spotlight.i);
},8000);
它可能并非在所有情况下都有效(取决于时间),但我希望对您有所帮助!
,您还必须认为您使用clearTimeout。
当您调用setTimeout函数时,它返回一个ID,您可以将此ID保存在一个变量中,例如
timeoutID = setTimeout(function () {
spotlight.animate(spotlight.i);
},8000);
在设置新超时之前,您可以调用如下函数
clearTimeout(timeoutID)
,我怀疑浏览器会将输入事件排入\'click \'之类,但仅在事件发生的选项卡实际上具有焦点时才触发它们。
也许您应该尝试直接调用点击回调,而不要使用trigger(\'click\')
。
像这样:
spotlight: {
i: 0,timeOutSpotlight: null,clickFunc: function(element) {
// do stuff here to count and move images
// Clear timeout
clearTimeout(spotlight.timeOutSpotlight);
// Some stuff here to calculate next item
// Call next spotlight in 8 seconds
spotlight.timeOutSpotlight = setTimeout(function () {
spotlight.animate(spotlight.i);
},8000);
},init: function()
{
$(\'#spotlight .controls a\').click(function (e) {
// Don\'t follow the link
e.preventDefault();
spotlight.clickFunc(this);
});
// Select first item
spotlight.clickFunc($(\'#spotlight .controls a.next:first\'));
},animate: function(i)
{
var element = $(\'#spotlight .controls li:eq(\'+spotlight.i+\') a.next\');
spotlight.clickFunc(element);
}
}
,您正在运行什么版本的jQuery?显然,此问题在1.6.3版中已“修复”,他们还原了导致这种情况发生的更改。这里和这里的讨论。
尽管将来可能必须解决此问题,但似乎我们暂时无法解决。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。