Html 如何正确迭代 getElementsByClassName
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15843581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to correctly iterate through getElementsByClassName
提问by Kupto
I am Javascript beginner.
我是 Javascript 初学者。
I am initing web page via the window.onload
, I have to find bunch of elements by their class name (slide
) and redistribute them into different nodes based on some logic. I have function Distribute(element)
which takes an element as input and does the distribution. I want to do something like this (as outlined for example hereor here):
我正在通过 初始化网页window.onload
,我必须通过它们的类名 ( slide
)找到一堆元素,并根据某些逻辑将它们重新分配到不同的节点。我有一个函数Distribute(element)
,它将一个元素作为输入并进行分布。我想做这样的事情(如此处或此处所述):
var slides = getElementsByClassName("slide");
for(var i = 0; i < slides.length; i++)
{
Distribute(slides[i]);
}
however this does not do the magic for me, because getElementsByClassName
does not actually return array, but a NodeList
, which is...
然而这对我来说并没有什么神奇之处,因为getElementsByClassName
实际上并没有返回数组,而是 a NodeList
,它是......
...this is my speculation...
……这是我的猜测……
...being changed inside function Distribute
(the DOM tree is being changed inside this function, and cloning of certain nodes happen). For-each
loop structure does not help either.
...在函数内部被改变Distribute
(DOM 树在这个函数内部被改变,并且发生了某些节点的克隆)。For-each
循环结构也无济于事。
The variable slides act's really un-deterministicaly, through every iteration it changes it's length and order of elements wildly.
变量 slides 的行为确实不确定,通过每次迭代,它都会疯狂地改变它的长度和元素顺序。
What is the correct way to iterate through NodeList in my case? I was thinking about filling some temporary array, but am not sure how to do that...
在我的情况下,迭代 NodeList 的正确方法是什么?我正在考虑填充一些临时数组,但不知道该怎么做...
EDIT:
编辑:
important fact I forgot to mention is that there might be one slide inside another, this is actually what changes the slides
variable as I have just found out thanks to user Alohci.
我忘记提及的一个重要事实是,另一张幻灯片中可能有一张幻灯片,这实际上是改变slides
变量的原因,因为我刚刚发现感谢用户Alohci。
The solution for me was to clone each element into an array first and pass the array ono-by-one into Distribute()
afterwards.
我的解决方案是首先将每个元素克隆到一个数组中,然后将数组一个一个地传递到其中Distribute()
。
回答by Albert Xing
According to MDN, the way to retrieve an item from a NodeList
is:
根据 MDN,从 a 中检索项目的方法NodeList
是:
nodeItem = nodeList.item(index)
Thus:
因此:
var slides = document.getElementsByClassName("slide");
for (var i = 0; i < slides.length; i++) {
Distribute(slides.item(i));
}
I haven't tried this myself (the normal for
loop has always worked for me), but give it a shot.
我自己还没有尝试过(正常for
循环一直对我有用),但试一试。
回答by styks
If you use the new querySelectorAll you can call forEach directly.
如果您使用新的 querySelectorAll,您可以直接调用 forEach。
document.querySelectorAll('.edit').forEach(function(button) {
// Now do something with my button
});
Per the comment below. nodeLists do not have a forEach function.
根据下面的评论。nodeLists 没有 forEach 函数。
If using this with babel you can add Array.from
and it will convert non node lists to a forEach array. Array.from
does not work natively in browsers below and including IE 11.
如果将它与 babel 一起使用,您可以添加Array.from
它,它将非节点列表转换为 forEach 数组。Array.from
不适用于以下浏览器(包括 IE 11)。
Array.from(document.querySelectorAll('.edit')).forEach(function(button) {
// Now do something with my button
});
At our meetup last night I discovered another way to handle node lists not having forEach
在我们昨晚的聚会上,我发现了另一种处理没有 forEach 的节点列表的方法
[...document.querySelectorAll('.edit')].forEach(function(button) {
// Now do something with my button
});
Showing as Node List
显示为节点列表
Showing as Array
显示为数组
回答by Andrew
You could always use array methods:
你总是可以使用数组方法:
var slides = getElementsByClassName("slide");
Array.prototype.forEach.call(slides, function(slide, index) {
Distribute(slides.item(index));
});
回答by ayjay
I followed Alohci's recommendation of looping in reverse because it's a live nodeList
. Here's what I did for those who are curious...
我遵循了Alohci的反向循环的建议,因为它是一个实时的nodeList
. 这是我为那些好奇的人所做的......
var activeObjects = documents.getElementsByClassName('active'); // a live nodeList
//Use a reverse-loop because the array is an active NodeList
while(activeObjects.length > 0) {
var lastElem = activePaths[activePaths.length-1]; //select the last element
//Remove the 'active' class from the element.
//This will automatically update the nodeList's length too.
var className = lastElem.getAttribute('class').replace('active','');
lastElem.setAttribute('class', className);
}
回答by Kushal Desai
<!--something like this-->
<html>
<body>
<!-- i've used for loop...this pointer takes current element to apply a
particular change on it ...other elements take change by else condition
-->
<div class="classname" onclick="myFunction(this);">first</div>
<div class="classname" onclick="myFunction(this);">second</div>
<script>
function myFunction(p) {
var x = document.getElementsByClassName("classname");
var i;
for (i = 0; i < x.length; i++) {
if(x[i] == p)
{
x[i].style.background="blue";
}
else{
x[i].style.background="red";
}
}
}
</script>
<!--this script will only work for a class with onclick event but if u want
to use all class of same name then u can use querySelectorAll() ...-->
var variable_name=document.querySelectorAll('.classname');
for(var i=0;i<variable_name.length;i++){
variable_name[i].(--your option--);
}
<!--if u like to divide it on some logic apply it inside this for loop
using your nodelist-->
</body>
</html>