简体   繁体   English

变量在for循环中变为undefined

[英]variable turns to undefined inside a for loop

I'm am battling with a javascript function I'm working on. 我正在与我正在努力的javascript函数作斗争。

Inside a for loop I'm iterating all elements with class "visible", inside that loop I'm preforming two actions. 在for循环中,我正在迭代所有带有“可见”类的元素,在该循环中我正在执行两个动作。

  1. elements[i].removeAttribute("class"); 元素[I] .removeAttribute( “类”);
  2. elements[i].setAttribute("class", "hidden"); elements [i] .setAttribute(“class”,“hidden”);

For some reason only 1 is valid. 出于某种原因,只有1是有效的。 2 produces an error saying: 2产生错误说:

Uncaught TypeError: Cannot call method 'setAttribute' of undefined

Even when I log elements[i] using console.log; 即使我使用console.log记录元素[i]; after the first console.log call the element exists, but on the second console.log elements[i] is 'undefined' 在第一个console.log调用后,该元素存在,但在第二个console.log元素[i]是'undefined'

What the hell am I missing here, this is driving me crazy, if my laptop wasn't so expensive it would have been broken by now. 我到底在这里错过了什么,这让我发疯,如果我的笔记本电脑不那么昂贵,那么它现在就会被打破。 Help :( 救命 :(

Here's the function: 这是功能:

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
    }
}

This is because getElementsByClassName returns a NodeList , which is live . 这是因为getElementsByClassName返回一个实时NodeList That is, it updates itself when the elements it refers to change. 也就是说,当它引用的元素发生变化时,它会自行更新。

When you remove the class attribute from an element in the NodeList , it gets removed from that list (since it no longer has the visible class name). NodeList的元素中删除class属性时,它将从该列表中删除(因为它不再具有visible类名)。

You don't actually need to remove the attribute. 您实际上不需要删除该属性。 Just setting it will do the job just as well. 设置它也可以完成这项工作。 But since the NodeList is changing as you manipulate the elements it contains, you need to count backwards through it (as each time you change one element of it, it is removed so the length decreases by one): 但是由于NodeList在操作它包含的元素时会发生变化,因此需要向后计数(因为每次更改它的一个元素时,它都会被删除,因此长度减少一个):

for (var i = elements.length - 1; i >= 0; i--) {
    elements[i].setAttribute("class", "hidden");
}

I think that the problem is elements[i].removeAttribute("class"); 我认为问题是elements[i].removeAttribute("class"); since you selected the element using a class getElementsByClassName("visible"); 因为您使用类getElementsByClassName("visible");选择了元素getElementsByClassName("visible"); . I think so when you remove class attribute completely from the element things are going wrong. 我认为当你从元素中完全删除类属性时,事情就出错了。

Try some tweak with the code. 尝试使用代码进行一些调整。 You are not suppose to remove attribute class if you are planning to use the same element which is selected using class attribute . 如果计划使用使用class属性选择的相同元素,则不应删除属性类

getElementsByClassName is a live NodeList so changing className of the items immediately affects whole list. getElementsByClassName是一个实时NodeList因此更改项的className会立即影响整个列表。 I would recommend use querySelectorAll insead. 我建议使用querySelectorAll insead。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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