问题:
采用全局变量movement作为函数变量,整个效果就是速度越来越快,而且不流畅,也就是动画滞后效果。
<body>
<h1 id="haha" style="position: absolute;top: 100px;left: 100px">O(∩_∩)O哈哈~</h1>
<script type="text/javascript">
window.onload=function(){
//这个100是top和left的初始值,改要一起修改。
move_h("haha",100,500,800);
}
function move_h(elem,f_x,f_y,speed){
var ha = document.getElementById(elem);
var e_l = parseInt(ha.style.left);
var e_t = parseInt(ha.style.top);
//向右移动
if(e_l>=f_x && e_l<f_y && e_t==f_x){
//每次移动50个像素
e_l+=50;
}
//向下移动
else if(e_l==f_y && e_t>=f_x && e_t<f_y){
e_t+=50;
}
//向左移动
else if(e_l>f_x && e_l<=f_y && e_t==f_y){
e_l-=50;
}
//向上移动
else if(e_l==f_x && e_t>f_x && e_t<=f_y){
e_t-=50;
}
//移动
ha.style.left = e_l+"px";
ha.style.top = e_t+"px";
var repeat = "move_h('"+elem+"',"+f_x+","+f_y+","+speed+")";
//将setInterval函数调用的返回值赋给变量
movement = setInterval(repeat,speed);
}
</script>
</body>
原因:
前面的movement还没执行完,后面的movement已经来了,那么movement在同一时刻会将元素向两个地方移动,所以在下一个movement来时要清除之前积累在settimeout队列里的事件。在这种情况下,movement不能用局部变量和全局变量,我们需要一个只与移动元素有关的变量——使DOM属性,把之前的函数变量movement变成自定义属性ha.movement。动画滞后现象消除。
代码:
<body>
<h1 id="haha" style="position: absolute;top: 100px;left: 100px">O(∩_∩)O哈哈~</h1>
<script type="text/javascript">
window.onload=function(){
//这个100是top和left的初始值,改要一起修改。
move_h("haha",100,500,800);
}
function move_h(elem,f_x,f_y,speed){
var ha = document.getElementById(elem);
//判断是否有movement属性,有就清除
if(ha.movement){
clearInterval(ha.movement);
}
var e_l = parseInt(ha.style.left);
var e_t = parseInt(ha.style.top);
//向右移动
if(e_l>=f_x && e_l<f_y && e_t==f_x){
//每次移动50个像素
e_l+=50;
}
//向下移动
else if(e_l==f_y && e_t>=f_x && e_t<f_y){
e_t+=50;
}
//向左移动
else if(e_l>f_x && e_l<=f_y && e_t==f_y){
e_l-=50;
}
//向上移动
else if(e_l==f_x && e_t>f_x && e_t<=f_y){
e_t-=50;
}
//移动
ha.style.left = e_l+"px";
ha.style.top = e_t+"px";
var repeat = "move_h('"+elem+"',"+f_x+","+f_y+","+speed+")";
//将setInterval函数调用的返回值赋给属性
ha.movement = setInterval(repeat,speed);
}
</script>
</body>