2

我正在与我正在处理的 javascript 函数作斗争。

在 for 循环中,我正在迭代所有具有“可见”类的元素,在该循环中,我正在执行两个操作。

  1. 元素[i].removeAttribute("class");
  2. 元素[i].setAttribute("class", "hidden");

出于某种原因,只有 1 是有效的。2产生一个错误说:

Uncaught TypeError: Cannot call method 'setAttribute' of undefined

即使我使用 console.log 记录元素[i];在第一个 console.log 调用后元素存在,但在第二个 console.log 元素 [i] 是“未定义”

我到底在想什么,这让我发疯了,如果我的笔记本电脑不是那么贵,它现在已经坏了。帮助 :(

这是功能:

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++)
    {
        console.log(elements[i]); // Works like a swiss clock

        elements[i].removeAttribute("class"); 

        console.log(elements[i]); // why elements[i] is 'undefined' now ???

        elements[i].setAttribute("class", "hidden"); // << turns to useless code
    }
}
4

3 回答 3

6

这是因为getElementsByClassName返回 a NodeList,它是live。也就是说,当它引用的元素发生变化时,它会自我更新。

当您class从 中的元素中删除该属性时NodeList,它会从该列表中删除(因为它不再具有visible类名)。

您实际上不需要删除该属性。只需设置它也可以完成这项工作。但是由于在NodeList您操作它包含的元素时它会发生变化,因此您需要通过它向后计数(因为每次更改它的一个元素时,它都会被删除,因此长度会减一):

for (var i = elements.length - 1; i >= 0; i--) {
    elements[i].setAttribute("class", "hidden");
}
于 2013-07-23T10:31:58.403 回答
1

我认为问题在于elements[i].removeAttribute("class"); 您使用 class 选择了元素getElementsByClassName("visible");。我认为,当您从元素中完全删除类属性时,事情就会出错。

尝试对代码进行一些调整。如果您打算使用使用 class attribute 选择的相同元素,则不应删除属性 class

于 2013-07-23T10:33:37.897 回答
1

getElementsByClassName是现场直播NodeList,因此项目的更改className会立即影响整个列表。我建议使用querySelectorAll insead。

加上而不是var body = document.getElementsByTagName("body");使用document.body.

于 2013-07-23T10:34:17.523 回答