效果图:
#案例:让盒子实现来链式运动

链式运动:是从一个动作运动到另一个动作,注意必须在动作执行完毕后才能进行下一个动作。

如果不判断fn的情况,那么盒子往下运动的时候会报错

#案例:使盒子执行完一系列动作,那么代码执行如下:

如果改为this(闭包),那么盒子不会完整执行一系列动作,它会停止。

停止的原因在于:执行的是fn函数(if(fn)fn();),因此需要使fn函数的this指向#当前对象(即让this指向136行的box节点,而box节点是152行的参数dom)
因此,让this指向dom,应写为:

#再作一个弹出,要求实现在完成一系列运动后再弹出一个弹窗


完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style>
*{margin: 0;padding: 0;}
#box{
width: 200px;
height: 200px;
background: skyblue;
position: absolute;
left: 0;
top: 0;
opacity: 0.3;
filter: alpha(opacity:30);
}
</style>
<body>
<div id="box"></div>
<script>
var box = document.getElementById("box");
box.onmouseover = function(){
animate(this,700,"left",function(){
animate(this,500,"top",function(){
animate(this,0,"left",function(){
animate(this,0,"top",function(){
alert("完成");
});
});
});
});
}
function animate(dom,target,attr,fn){
//dom ===》DOM节点
//target ===》目标值
//attr ===》属性名称
//fn ===》回调函数
clearInterval(dom.timer);
dom.timer = setInterval(function(){
if(attr=="opacity"){
var objAttr= parseFloat(getAttr(dom,attr))*100;
}else{
var objAttr = parseInt(getAttr(dom,attr));
}
var speed = (target-objAttr)/10;
speed = speed>0 ?Math.ceil(speed):Math.floor(speed);
if(target == objAttr){
//停止定时器
clearInterval(dom.timer);//执行完毕
//由于第5行没有写参数fn(会报错),因此需要判断fn的情况
if(fn){
fn.call(dom);
}
}else{
if(attr=="opacity"){
dom.style.filter = "alpha(opacity:"+objAttr + speed+")";//IE
dom.style[attr] = (objAttr + speed)/100;
}else{
dom.style[attr] = objAttr + speed +"px";
}
}
},30)
}
function getAttr(dom,attr){
if(dom.currentStyle){
return dom.currentStyle[attr];
}else{
return getComputedStyle(dom,null)[attr];
}
}
</script>
</body>
</html>
这篇博客探讨了如何在JavaScript中实现链式运动,强调了动作执行顺序的重要性,并通过示例解释了如何避免在运动过程中出现错误。文章通过案例展示了如何确保盒子在完成一系列连续动作后正确执行,讨论了闭包和`this`上下文的问题,以及如何通过修改`this`的指向来确保运动序列的顺利完成。最后,提出了一个要求在运动序列完成后弹出弹窗的挑战,并给出了完整的代码实现。
894

被折叠的 条评论
为什么被折叠?



