web-dev-qa-db-fra.com

Comment faire cette boucle tous les enfants récursivement?

J'ai le suivant:

for (var i = 0; i < children.length; i++){
   if(hasClass(children[i], "lbExclude")){
       children[i].parentNode.removeChild(children[i]);
   }
};

Je voudrais qu'il passe en revue tous les enfants des enfants, etc. (pas seulement le niveau supérieur). J'ai trouvé cette ligne, qui semble faire ça:

for(var m = n.firstChild; m != null; m = m.nextSibling) {

Mais je ne sais pas comment je me réfère à l'enfant actuel si je fais ce changement? Je n'aurais plus besoin de clarifier la position d'index de l'enfant. Aucune suggestion?

Merci!

Mettre à jour:

J'utilise maintenant les éléments suivants, selon les suggestions de réponses. Est-ce la manière correcte/la plus efficace de le faire?

function removeTest(child) {
  if (hasClass(child, "lbExclude")) {
    child.parentNode.removeChild(child);
  }
}

function allDescendants(node) {
  for (var i = 0; i < node.childNodes.length; i++) {
    var child = node.childNodes[i];
    allDescendants(child);
    removeTest(child);
  }
}

var children = temp.childNodes;
for (var i = 0; i < children.length; i++) {
  allDescendants(children[i]);
};
23
Matrym

Normalement, vous auriez une fonction qui pourrait être appelée de manière récursive sur tous les nœuds. Cela dépend vraiment de ce que vous voulez faire aux enfants. Si vous voulez simplement rassembler tous les descendants, alors element.getElementsByTagName peut être une meilleure option.

var all = node.getElementsByTagName('*');

for (var i = -1, l = all.length; ++i < l;) {
    removeTest(all[i]);
}
28
James
function allDescendants (node) {
    for (var i = 0; i < node.childNodes.length; i++) {
      var child = node.childNodes[i];
      allDescendants(child);
      doSomethingToNode(child);
    }
}

Vous passez en boucle sur tous les enfants et pour chaque élément, vous appelez la même fonction et le faites passer en boucle sur les enfants de cet élément.

40
Quentin

Il n'est pas nécessaire d'appeler la méthode 'allDescendants' sur tous les enfants, car la méthode elle-même le fait déjà. Donc, supprimez le dernier code et je pense que c'est une solution appropriée (á, pas le =])

            function removeTest(child){     
                if(hasClass(child, "lbExclude")){
                    child.parentNode.removeChild(child);
                }
            }

            function allDescendants (node) {
                for (var i = 0; i < node.childNodes.length; i++) {
                  var child = node.childNodes[i];
                  allDescendants(child);
                  removeTest(child);
                }
            }           

            var children = allDescendants(temp);
3

si des éléments sont créés en boucle, vous devez laisser un index via id = "" nom-donnée ou quelque chose. Vous pouvez ensuite les indexer directement, ce qui sera plus rapide pour la plupart des fonctions telles que (! -F). Fonctionne assez bien pour 1024 bits x 100 éléments en fonction de ce que vous faites.

if ( document.getElementById( cid ) ) {
 return;
} else {
  what you actually want
}

ce sera plus rapide dans la plupart des cas, une fois que les éléments ont déjà été chargés. ne frottez la page que sur recharger/transférer des domaines/connexions/cors de domaine sécurisés et que vous fassiez quelque chose deux fois.

1
user10794722

Vous pouvez utiliser BFS pour trouver tous les éléments.

function(element) {
    // [].slice.call() - HTMLCollection to Array
    var children = [].slice.call(element.children), found = 0;
    while (children.length > found) {
        children = children.concat([].slice.call(children[found].children));
        found++;
    }
    return children;
};

Cette fonction renvoie tous les enfants des enfants de l'élément.

1
androbin

Si vous avez jquery et que vous voulez obtenir tous les éléments descendants, vous pouvez utiliser:

 var all_children= $(parent_element).find('*');

Sachez simplement que all_children est une collection HTML et non un tableau. Ils se comportent de la même façon lorsque vous bouclez, mais la collection ne contient pas beaucoup des méthodes Array.prototype utiles que vous pourriez autrement apprécier. 

1
Luke

La façon la plus claire de le faire dans les navigateurs modernes ou avec Babel est la suivante. Supposons que vous avez un nœud HTML $node dont vous voulez rediffuser les enfants.

Array.prototype.forEach.call($node.querySelectorAll("*"), function(node) {
  doSomethingWith(node);
});

La querySelectorAll('*') sur n'importe quel noeud DOM vous donnerait tout les noeuds enfant de l'élément dans une NodeList. NodeList est un objet de type tableau, vous pouvez donc utiliser le Array.prototype.forEach.call pour parcourir la liste, en traitant chaque enfant un par un dans le rappel.

0
kumar_harsh

Si vous utilisez une bibliothèque js, c'est aussi simple que cela:

$('.lbExclude').remove();

Sinon, si vous souhaitez acquérir tous les éléments sous un nœud, vous pouvez les collecter tous de manière native:

var nodes = node.getElementsByTagName('*');
for (var i = 0; i < nodes.length; i++) {
  var n = nodes[i];
  if (hasClass(n, 'lbExclude')) {
    node.parentNode.removeChild(node);
  }
}
0
wombleton