Как правильно выполнить итерацию через getElementsByClassName
Я начинаю Javascript.
Я запускаю веб-страницу через window.onload
, мне нужно найти кучу элементов по их имени класса (slide
) и перераспределить их на разные узлы на основе некоторой логики. У меня есть функция Distribute(element)
, которая принимает элемент как входной и выполняет распределение. Я хочу сделать что-то вроде этого (как описано здесь здесь или здесь):
var slides = getElementsByClassName("slide");
for(var i = 0; i < slides.length; i++)
{
Distribute(slides[i]);
}
однако это не делает для меня волшебство, потому что getElementsByClassName
фактически не возвращает массив, а NodeList
, который...
... это мое предположение...
... изменяется внутри функции Distribute
(дерево DOM изменяется внутри этой функции, и происходит клонирование некоторых узлов). Строковая структура For-each
не помогает.
Переменные слайды действуют на самом деле не детерминированно, через каждую итерацию он сильно изменяет длину и порядок элементов.
Каков правильный способ итерации через NodeList в моем случае? Я думал о заполнении некоторого временного массива, но не знаю, как это сделать...
EDIT:
Важным фактом я забыл упомянуть, что может быть один слайд внутри другого, на самом деле это изменяет переменную slides
, как я только что узнал благодаря пользователю Alohci.
Решение для меня заключалось в том, чтобы сначала клонировать каждый элемент в массив и передать его по очереди один раз в Distribute()
.
Ответы
Ответ 1
Согласно MDN, способ получить элемент из NodeList
:
nodeItem = nodeList.item(index)
Таким образом:
var slides = document.getElementsByClassName("slide");
for(var i = 0; i < slides.length; i++)
{
Distribute(slides.item(i));
}
Я не пробовал это сам (нормальный цикл for
всегда работал у меня), но дайте ему шанс.
Ответ 2
Если вы используете новый querySelectorAll, вы можете напрямую вызвать forEach.
document.querySelectorAll('.edit').forEach(function(button) {
// Now do something with my button
});
В комментарии ниже. nodeLists не имеют функции forEach.
Если вы используете это с babel, вы можете добавить Array.from
и он преобразует списки не узлов в массив forEach. Array.from
не работает в браузерах ниже и включает IE 11.
Array.from(document.querySelectorAll('.edit')).forEach(function(button) {
// Now do something with my button
});
На нашей встрече прошлой ночью я обнаружил другой способ обработки списков узлов, не имеющих foreach
[...document.querySelectorAll('.edit')].forEach(function(button) {
// Now do something with my button
});
Поддержка браузера для [...]
Отображение списка узлов
![Showing as Node List]()
Отображение в виде массива
![Showing as Array]()
Ответ 3
Вы всегда можете использовать методы массива:
var slides = getElementsByClassName("slide");
Array.prototype.forEach.call(slides, function(slide, index) {
Distribute(slides.item(index));
});
Ответ 4
Я последовал за 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 length too.
var className = lastElem.getAttribute('class').replace('active','');
lastElem.setAttribute('class', className);
}
Ответ 5
<!--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>