setInertval间隔时间问题

来源:互联网 发布:简述java变量命名规则 编辑:程序博客网 时间:2024/04/29 16:27

假设我们有一个滚动条长为50px,我们想要设置在两秒内滚动到终点。

<div id='slide'>

<div id='move'></div>

</div>

一般情况下

我们想要move模块在两秒内从slide最左边滑动到最右边,相当于一个动画;一般我们去用setInterval解决方式如下:

var move=document.getElementById("move");

var interval=window.setInterval(function(){

var left=parseFloat(document.getElementById('move').style.left);

left<50?move.style.left=left+1+"px":clearInterval(interval);

},40);

在这里我们将2s转化为2000ms对应50px,相当于40ms对应一个像素。于是将间隔时间设置为40ms;这样一来每隔40ms move模块就会向右滑动一个像素。

理想很丰满,现实很骨感。。。

现在很多浏览器都将setInterval间隔时间设置了最小值,尤其是你当将页面隐藏或者最小化时候,很多浏览器会将你设置的间隔时间修改为1000ms(如果间隔时间小于1000ms);

这样的话本来两秒钟我们认为能执行完的事件,如果一开始就将其最小化,那么会执行1000/40倍也就是会花费25*2秒。明白了不?

换句话说 浏览器会将你的间隔时间变大,导致你里面事件执行的间隔变大。但是里面事件是由时间间隔驱动的,多久执行一次都会+1像素。

所以这样就导致了问题的出现----如何预防间隔时间不准确?

其实目前很多动画的实现都不会简单去应用上述的写法。就跟看视频一样,间隔一段时间回去页面再看时候 大部分都是乍一看还在离开时候,然后突然就会跳到现在应该播放的帧而不会“慢放”。

所以我们应该不去考虑到底设计间隔多久而应该考虑 多久能执行完。不知道绕晕了没??哈哈

解释一下:setInterval里面的函数执行事件 是基于你设定的间隔去执行事件,如果我们太过于依赖于间隔(如上例子)就会导致上述问题(我们事件都是基于间隔去计算的)。

所以我们应该不去管间隔到底是多少毫秒(当然你不能将间隔设置的不靠谱,本来2s执行完的动画 1s动一下估计就啪啪两下到头了,很是不舒服)而应该像视频播放一样去设计我们的定时器:

在正常间隔执行事件下去正常执行事件,在间隔被扩大后我们在事件内部处理这个时间段到底应该走到了哪里!看代码:

var move=document.getElementById('move'),start=new Date().getTime(),end=2000,

var inter=window.setInterval(function(){

var now=new Date().getTime(),space=now-start, left=parseFloat(document.getElementById('move').style.left);

left<50?move.style.left=(space-start)/40+'px':clearInterval(inter);

},40)

上面代码在事件中增加了对当前时间以及开始时间的计算,用这种方式去辅助间隔时间引起的bug问题。也就是说在正常情况下上述代码是40ms走1个像素,2s正好会到达50px。当浏览器将间隔变大后,假设浏览器将间隔修改为1000ms,并且一开始就修改了。

这样我们在一秒之后回去看的时候进度条就会根据事件的时间去计算1s内到底应该走到哪,这样就会跟视频播放一样的效果,进度条不会滞后,也不会因为间隔边长引起的事件处理bug。

0 0