繁体   English   中英

Javascript的setTimeout函数没有调用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM