setTimeout()
在全局范围内执行字符串参数,因此您的值this
不再存在,您的参数也不再存在caller
。这是不将字符串参数与 setTimeout 一起使用的众多原因之一。使用像这样的实际 javascript 函数引用,解决相应地传递参数是一个非常简单的问题:
function mve(caller){
caller.style.position = "relative";
caller.style.left = (caller.style.left+20) +'px';
setTimeout(function() {
mve(caller)
}, 2000);
}
对于你的问题的第二部分,caller.style.left
它上面会有单位,20px
所以当你添加20
它时,你会得到20px20
,这不是浏览器可以理解的值,所以什么也不会发生。您需要从中解析出实际数字,将数字加 20,然后像这样重新添加单位:
function mve(caller){
caller.style.position = "relative";
caller.style.left = (parseInt(caller.style.left), 10) +20) + 'px';
setTimeout(function() {
mve(caller)
}, 2000);
}
此功能缺少的东西是它停止重复的一种方式。正如你现在拥有的那样,它会永远持续下去。我可能会建议像这样传递一些迭代:
function mve(caller, iterationsRemaining){
caller.style.position = "relative";
caller.style.left = (parseInt(caller.style.left), 10) +20) + 'px';
if (--iterationsRemaining) > 0) {
setTimeout(function() {
mve(caller, iterationsRemaining)
}, 2000);
}
}
此外,您可能很想知道这并不是真正的递归函数。那是因为mve()
函数调用setTimeout()
然后立即完成。它是在一段时间后setTimeout()
执行下一次迭代,mve()
并且多个函数调用的堆栈帧上没有累积,因此没有实际的递归。从代码上看,它确实看起来像递归,但在技术上不是。