问题简述:本代码较长,建议拷贝到编辑器查看。问题是使用两种js方法完成一个效果,个人认为两种方法原理一样,但是一个效果出来了,一个没有出效果并且报错,想知道报错的原因,望大神指教。
HTML代码:
<p>用 requestAnimationFrame 替代 seTtimeout 实现了一个动画效果:</p>
<div>
<p class="ball red" style="margin-left:0px;"></p>
<p class="ball green" style="margin-left:0px;"></p>
<p class="ball blue" style="margin-left:0px;"></p>
</div>
CSS代码:
.ball {
width: 20px;
height: 20px;
border-radius: 50%;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
JavaScript代码方法一:
var red = document.querySelector(".red");
var green = document.querySelector(".green");
var blue = document.querySelector(".blue");
ani(red, 100, function() {
ani(green, 200, function() {
ani(blue, 150, function() {
ani(red, 150);
ani(green, 150)
})
})
})
//代码一
function ani(node, to, callback) {
animate();
function animate() {
var marginLeft = parseInt(node.style.marginLeft);
if (marginLeft == to) {
callback && callback();
} else {
if (marginLeft < to) {
marginLeft++
} else if (marginLeft > to) {
marginLeft--
}
node.style.marginLeft = marginLeft + "px";
requestAnimationFrame(animate);
}
}
}
效果没问题:
JavaScript代码方法二:
var red = document.querySelector(".red");
var green = document.querySelector(".green");
var blue = document.querySelector(".blue");
ani(red, 100, function() {
ani(green, 200, function() {
ani(blue, 150, function() {
ani(red, 150);
ani(green, 150)
})
})
})
function ani(node, to, callback) {
var marginLeft = parseInt(node.style.marginLeft); //本行报错,说不识别属性marginLeft
if (marginLeft == to) {
callback && callback();
} else {
if (marginLeft < to) {
marginLeft++
} else if (marginLeft > to) {
marginLeft--
}
node.style.marginLeft = marginLeft + "px";
requestAnimationFrame(ani);
}
}
效果报错:
问题:这两种方案的差别是什么?为什么第二种方案会报错?
等价于:
那么问题来了,你 ani 函数里面的各个参数必然是 undefined 啊,所以会报错咯。
另外,你第一种方法,既然使用 requestAnimationFrame 了,本质上是一个递归的逻辑,所以不用手动触发 animate 方法,直接在最后写 requestAnimationFrame(animate) 就可以了。
最后,说点儿题外话,可能你有你自己的考虑,但是如果是做这种平移的特效,建议使用 transform,效果会比 margin 好。