我正在与我正在努力的javascript函数作斗争。
在for循环中,我在该循环内迭代所有带有“visible”类的元素 我正在做两件事。
出于某种原因,只有1是有效的。 2产生错误说:
Uncaught TypeError: Cannot call method 'setAttribute' of undefined
即使我使用console.log记录元素[i];在第一次console.log调用之后 元素存在,但在第二个console.log元素[i]是'undefined'
如果我的笔记本电脑不那么昂贵,我在这里错过了什么,这让我发疯了 它现在已经被打破了。帮助:(
这是功能:
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
}
}
答案 0 :(得分:6)
这是因为getElementsByClassName
会返回NodeList
, live 。也就是说,当它引用的元素发生变化时,它会自动更新。
当您从class
中的元素中删除NodeList
属性时,它会从该列表中删除(因为它不再具有visible
类名称。)
您实际上不需要删除该属性。设置它也可以完成这项工作。但是由于NodeList
在操作它包含的元素时会发生变化,因此需要向后计数它(因为每次更改它的一个元素时,它都被移除,因此长度减少一个):
for (var i = elements.length - 1; i >= 0; i--) {
elements[i].setAttribute("class", "hidden");
}
答案 1 :(得分:1)
我认为问题是elements[i].removeAttribute("class");
,因为您使用类getElementsByClassName("visible");
选择了元素。我认为当你从元素中完全删除类属性时,事情就出错了。
尝试使用代码进行一些调整。 如果您打算使用使用类属性选择的相同元素,则不会删除属性类。
答案 2 :(得分:1)
getElementsByClassName
是实时NodeList
,因此更改className
项会立即影响整个列表。我建议使用querySelectorAll insead。
而不是var body = document.getElementsByTagName("body");
使用document.body
。