扫码关注官方订阅号
Document
光阴似箭催人老,日月如移越少年。
代码啥的无大碍,就是变量作用域没有分离开,简单的说在你的循环里打个闭包(构建新的作用域)就可以了。
主要问题在于每个li动画的状态都是不可共享的,每个li有自己的timer时间和alpha透明度,如果每个动画状态被共享(就是题主之前的代码),就会出现以下这种情况:
li
timer时间
alpha透明度
鼠标移入第一张图片a,执行startMove,setInterval开始根据间隔反复执行。
a
startMove
setInterval
比如第一张图片alpha透明度执行到了0.7的时候,移动鼠标到了第二张图片:
0.7
第一张图片执行onmouseout,执行startMove(this, 0.3),但是它是一个异步任务,所以被挂到event loop,在300ms之后执行(关于event loop以及它的异步流程请参考我的这边文章:《JavaScript下的setTimeout(fn,0)意味着什么?》)。
onmouseout
startMove(this, 0.3)
异步任务
event loop
接着第二张图片的也执行了startMove,但是它的alpha和timer都是第一张图片的状态,此时它直接清空了timer,造成的结果就是第一张图片被挂起的300ms任务被clear掉了。
alpha
timer
clear
接着题主就看到了bug现象:第二张发生了动画opacity=1,但是第一张图片opacity也是1
具体修正的代码如下,只需要把共享的变量alpha & timer放到闭包里即可:
alpha & timer
var oImg = document.getElementById('imglist'); var oImgLi = oImg.getElementsByTagName('li'); //ES5的func Array.prototype.forEach.call(oImgLi, function (img) {//传递回调函数,构建新的作用域 //timer、alpha和startMove,不应该被每个li共享使用,因为每个li都有自己的状态,自己的动画状态(自己的动画时长,alpha透明度) var timer = null, alpha = 0.3; function startMove(obj, iTarget) { clearInterval(timer); timer = setInterval(function () { var speed = 0; if (alpha < iTarget) { speed = 0.1; } else { speed = -0.1; } if (alpha === iTarget) { clearInterval(timer); } else { alpha = (alpha * 10 + speed * 10) / 10; obj.style.opacity = alpha; obj.style.filter = "alpha(opacity=" + alpha * 100 + ")"; } }, 30); } img.onmouseover = function () { startMove(this, 1); }; img.onmouseout = function () { startMove(this, 0.3); }; });
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
代码啥的无大碍,就是变量作用域没有分离开,简单的说在你的循环里打个闭包(构建新的作用域)就可以了。
主要问题在于每个
li动画的状态都是不可共享的,每个li有自己的timer时间和alpha透明度,如果每个动画状态被共享(就是题主之前的代码),就会出现以下这种情况:鼠标移入第一张图片
a,执行startMove,setInterval开始根据间隔反复执行。比如第一张图片
alpha透明度执行到了0.7的时候,移动鼠标到了第二张图片:第一张图片执行
onmouseout,执行startMove(this, 0.3),但是它是一个异步任务,所以被挂到event loop,在300ms之后执行(关于event loop以及它的异步流程请参考我的这边文章:《JavaScript下的setTimeout(fn,0)意味着什么?》)。接着第二张图片的也执行了
startMove,但是它的alpha和timer都是第一张图片的状态,此时它直接清空了timer,造成的结果就是第一张图片被挂起的300ms任务被clear掉了。接着题主就看到了bug现象:第二张发生了动画opacity=1,但是第一张图片opacity也是1
具体修正的代码如下,只需要把共享的变量
alpha & timer放到闭包里即可: