0

我的问题很简单。我在 for 循环中使用 setTimeout ,在运行时产生错误说:

Uncaught TypeError: Cannot call method 'setAttribute' of undefined

我对 javascript 的经验很少(为了学习,我跳过了 jQuery),我认为这与我调用 setTimeout 的方式有关。

看看我的函数,我想知道为什么匿名函数内部没有“元素”。

function hide_visable_elements()
{
    // remove body EventListener
    var body = document.getElementsByTagName("body");
    body[0].removeEventListener("click", hide_visable_elements, true);

    var elements = document.getElementsByClassName("visible");
    for (var i = 0; i < elements.length; ++i)
    {
    elements[i].removeAttribute("class");
    setTimeout(function() { elements[i].setAttribute("class", "hidden") }, 300);
    }   
}
4

1 回答 1

1

这是一个示例,说明如何捕获迭代的当前值,以便在循环完成后执行它时(由于异步性质,它始终after),它将做正确的事情:

function setHidden(element) {
    return function() {
        element.setAttribute("class", "hidden");
    };
}

function hide_visable_elements() {
    // remove body EventListener
    var body = document.getElementsByTagName("body");
    body[0].removeEventListener("click", hide_visable_elements, true);
    var elements = document.getElementsByClassName("visible");
    for (var i = 0; i < elements.length; ++i) {
        elements[i].removeAttribute("class");
        setTimeout(setHidden(elements[i]), 300);
    }
}


顺便说一句,我相对使用“很久之后”的描述,在您的延迟函数可能执行之前经过的最短时间是 4 或 13 毫秒,但循环执行时间以微秒或纳秒为单位测量。

于 2013-07-21T15:55:48.910 回答