![](/img/trans.png)
[英]Calling a callback function that returns a setTimeOut callback javascript
[英]Javascript's setTimeout function not calling
setTimeout函数总是给我带来麻烦。 现在我有一个递归的函数(通过setTimeout调用自身)并更改元素高度。
该函数发送两个参数:要更改的元素和元素的最大高度。 该功能的目的是展开元素,或以恒定的速度“向下滑动”。 我知道我可以用jQuery解决这个问题,但我正在尝试自己的功能。
function slide_down(element, max_height)
{
if(element.clientHeight < max_height)
{
var factor = 10;
var new_height = (element.clientHeight + factor >= max_height) ? max_height : (element.clientHeight + factor);
element.style.height = new_height + 'px';
var func_call = 'slide_down(' + element + ', ' + max_height + ');';
window.setTimeout(func_call, 10);
}
}
我在最初调用函数时测试了参数。 max_height设置为20,因为它是所需的高度元素(我从.scrollHeight获得此值)。
当函数完成后,我想让它自己调用,直到max_height是元素的高度。 我用这个setTimeout调用来做到这一点:
var func_call = 'slide_down(' + element + ', ' + max_height + ');';
window.setTimeout(func_call, 10);
它不起作用。 这确实有效:
var func_call = 'alert(1);';
window.setTimeout(func_call, 10);
我也尝试将函数调用直接放入setTimeout语句,仍然无法正常工作。
请注意,元素的高度DOES会更改第一次迭代,该函数永远不会调用自身。 所以元素变量设置正确,我使用alert()来显示max_height也是正确的。
alert(func_call);
提醒:
slide_down([object HTMLParagraphElement], 20);
当你这样做:
var func_call = 'slide_down(' + element + ', ' + max_height + ');';
你正在将元素转换为字符串,所以你的超时会是这样的
slide_down("[Object]", 100);
这显然是行不通的。
你应该做的是创建一个闭包 - 它有点复杂,但基本上你创建了一个函数,旧函数中的局部变量仍然可以在新函数中使用。
function slide_down(element, max_height)
{
if(element.clientHeight < max_height)
{
var factor = 10;
var new_height = (element.clientHeight + factor >= max_height) ? max_height : (element.clientHeight + factor);
element.style.height = new_height + 'px';
var func = function()
{
slide_down(element, max_height);
}
window.setTimeout(func, 10);
}
}
10还有一点暂停 - 我建议至少使用50。
首先,这个“现在我有一个递归的函数(通过setTimeout调用自己)”如果你没有改变周期,就会向我发出尖叫声setInterval 。
其次,这是因为元素引用在字符串concat中丢失,因为element.toString()将是“[object]”。 尝试传入一个你可以重新找到的id,存储一个级别的引用,或者(正如我刚刚看到matt b指出的那样)扩展的方法表单。
编写方法的一种更微妙的方式(作为Gregs答案的扩展):
function slide_down(element, max_height)
{
if(element.clientHeight < max_height)
{ return; }
var factor = 10,
new_height = element.clientHeight + factor,
f = arguments.callee;
if( new_height > max_height )
{ new_height = max_height; }
element.style.height = new_height + 'px';
window.setTimeout(function() { f(element, max_height); }, 10);
}
这个示例代码的真正优点是使用了arguments.callee
。 这样你就不会破坏你的功能,如果你决定重命名它。 我还简化了new_height
值赋值。 旧代码中的问题是你执行了两次element.clientHeight + factor
,这有点无关紧要。 并不是说在这种情况下它对你的表现有任何明显的影响。 但是避免一遍又一遍地计算相同的东西总是好的,但只是存储结果供以后使用。
我有类似的经历。 当你下次传递元素时,它会在函数调用中转换为字符串,所以当函数运行时,它会尝试找到一个名为[object] .string或者其他东西的元素,而不是你想要的东西。
尝试更改函数参数以获取元素的id并执行document.getElementById()调用函数内部的第一件事。
代码的问题在于您无法传递元素参数。
代替:
var func_call = 'slide_down(' + element + ', ' + max_height + ');'; window.setTimeout(func_call, 10);
尝试使用匿名函数:
window.setTimeout(function() { slide_down(element, max_height) }, 10);
@ matt.b:IE中不支持传入setTimeout调用的参数(你的方式)。
两件事情:
1.有另一种方法可以调用setTimeout()
在其中传递函数和参数,而不是要执行的字符串。 实际上, Gecko DOM手册指出不建议使用您的调用setTimeout()
版本。
代替:
var func_call = 'slide_down(' + element + ', ' + max_height + ');';
window.setTimeout(func_call, 10);
试试这个:
window.setTimeout(slide_down, 10, element, max_height);
更新 :正如RoBorg所说,这在IE中可能不起作用,所以你不妨忽略它。
2.我觉得从setTimeout()
调用的函数中调用setTimeout()
是不允许的,或者不能正常工作。 我假设您正在链接这样的调用,因为您希望代码重复执行? 如果是这样,那就是window.setInterval()
的用途。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.