web-dev-qa-db-fra.com

Comment parcourir correctement getElementsByClassName

Je suis débutant en Javascript.

Je lance une page Web via le window.onload. Je dois trouver un groupe d’éléments par leur nom de classe (slide) et les redistribuer dans différents nœuds en fonction d’une logique. J'ai la fonction Distribute(element) qui prend un élément en entrée et effectue la distribution. Je veux faire quelque chose comme ceci (comme indiqué par exemple ici ou ici ):

var slides = getElementsByClassName("slide");
for(var i = 0; i < slides.length; i++)
{
   Distribute(slides[i]);
}

cependant cela ne fait pas la magie pour moi, parce que getElementsByClassName ne renvoie pas réellement un tableau, mais un NodeList , qui est ...

... c'est ma spéculation ...

... en cours de modification dans la fonction Distribute (l'arborescence DOM est en cours de modification dans cette fonction et le clonage de certains nœuds a lieu). La structure de la boucle For-each N'aide pas non plus.

La variable variable act est vraiment non déterministe, à chaque itération, sa longueur et son ordre d'éléments changent brutalement.

Quelle est la bonne façon de parcourir NodeList dans mon cas? Je pensais à remplir un tableau temporaire, mais je ne sais pas comment faire cela ...

EDIT:

un fait important que j'ai oublié de mentionner, c’est qu’il pourrait y avoir une diapositive dans une autre, c’est en fait ce qui modifie la variable slides que je viens de découvrir grâce à l’utilisateur Alohci .

La solution pour moi était de cloner d'abord chaque élément dans un tableau, puis de le passer un par un dans Distribute().

71
Kupto

Selon MDN, le moyen de récupérer un élément à partir d'un NodeList est le suivant:

nodeItem = nodeList.item(index)

Ainsi:

var slides = document.getElementsByClassName("slide");
for(var i = 0; i < slides.length; i++)
{
   Distribute(slides.item(i));
}

Je n'ai pas essayé moi-même (la boucle normale for a toujours fonctionné pour moi), mais tentez votre chance.

100
Albert Xing

Si vous utilisez le nouveau querySelectorAll, vous pouvez appeler directement forEach.

document.querySelectorAll('.edit').forEach(function(button) {
    // Now do something with my button
});

D'après le commentaire ci-dessous. nodeLists n'a pas de fonction forEach.

Si vous utilisez ceci avec babel, vous pouvez ajouter Array.from et il convertira les listes de noeuds en un tableau forEach. Array.from ne fonctionne pas nativement dans les navigateurs ci-dessous, y compris IE 11.

Array.from(document.querySelectorAll('.edit')).forEach(function(button) {
    // Now do something with my button
});

Lors de notre rencontre la nuit dernière, j'ai découvert un autre moyen de gérer des listes de noeuds n'ayant pas forEach

[...document.querySelectorAll('.edit')].forEach(function(button) {
    // Now do something with my button
});

Prise en charge du navigateur pour [...]

Afficher comme Node List

Showing as Node List

Affichage en tant que tableau

Showing as Array

48
styks

Vous pouvez toujours utiliser des méthodes de tableau:

var slides = getElementsByClassName("slide");
Array.prototype.forEach.call(slides, function(slide, index) {
    Distribute(slides.item(index));
});
8
Andrew

J'ai suivi la recommandation de Alohci de boucler à l'envers parce que c'est un live nodeList. Voici ce que j'ai fait pour ceux qui sont curieux ...

  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);
  }
7
ayjay
 <!--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>
1
Kushal Desai