Подтвердить что ты не робот

Как правильно выполнить итерацию через 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().

4b9b3361

Ответ 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>