<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
ul,li{
list-style: none;
}
.imglist {
width: 1000px;
height: 400px;
}
.imglist ul {
width: 1000px;
overflow: hidden;
}
.imglist ul li.item {
width: 200px;
height: 400px;
float: left;
opacity: 0.3;
filter: alpha(opacity=30);
}
.imglist ul li.item img {
width: 200px;
height: 400px;
float: left;
}
</style>
</head>
<body>
<div class="imglist">
<ul id="imglist">
<li class="item i1"><img src="1.jpg" alt=""></li>
<li class="item i2"><img src="1.jpg" alt=""></li>
<li class="item i3"><img src="1.jpg" alt=""></li>
<li class="item i4"><img src="1.jpg" alt=""></li>
<li class="item i5"><img src="1.jpg" alt=""></li>
</ul>
</div>
<script>
window.onload = function () {
var oImg = document.getElementById('imglist');
var oImgLi = oImg.getElementsByTagName('li');
var alpha = 0.3;
var i=0;
var timer = null;
var flag = true;
for(len=oImgLi.length;i<len;i++){
oImgLi[i].onmouseover = function () {
startMove(this,1);
};
oImgLi[i].onmouseout = function () {
startMove(this,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);
}
};
</script>
</body>
</html>
代码啥的无大碍,就是变量作用域没有分离开,简单的说在你的循环里打个闭包(构建新的作用域)就可以了。
主要问题在于每个
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
放到闭包里即可: