Obtenez tous les éléments dans un document HTML avec une classe CSS spécifique

Quelle est la meilleure façon d'obtenir un tableau de tous les éléments dans un document html avec une classe CSS spécifique à l'aide de javascript?

Aucun cadre javascript comme jQuery n'est autorisé ici maintenant, et je pourrais faire la boucle de tous les éléments et les vérifier manuellement. J'espère que quelque chose d'un peu plus élégant.

La réponse ci-dessous présente maintenant quatre ans, donc il est intéressant de noter que le support de navigateur natif pour getElementsByClassName() a bien amélioré. Mais si vous devez supporter des navigateurs plus anciens, alors …

Utilisez un qui a déjà été écrit. La plupart des bibliothèques majeures de JS incluent une sous une forme ou une autre, mais si vous n'utilisez pas l'une d'entre elles, je peux recommander l'excellente implémentation de Robert Nyman:

http://code.google.com/p/getelementsbyclassname/
http://www.robertnyman.com/2008/05/27/the-ultimate-getelementsbyclassname-anno-2008/

Il y a trop de façons de rendre cette routine (conceptuellement simple) lente et buggy pour justifier l'écriture de votre propre implémentation à ce stade.

1) Obtenez tous les éléments du document (document.getElementsByTagName ('*'))
2) Faites une correspondance d'expression régulière sur l'attribut className de l'élément pour chaque élément

Vous pouvez inclure une fonction getElementsByClass , ou vous pouvez utiliser un sélecteur jQuery .

MISE À JOUR: La mise en œuvre mentionnée par @ Shog9 est probablement meilleure que celle ci-dessus.

Juste pour faire un suivi, j'ai basé mon code sur la mise en œuvre de Robert Nyman posté par Shog9, mais je me suis éloigné un peu de sa version exacte, pour trois raisons:

  1. Il vous a permis de sélectionner un élément racine et un type d'étiquette pour filtrer vos résultats. Je n'ai pas besoin de cette fonctionnalité et, en le supprimant, j'ai pu simplifier considérablement le code.
  2. La première chose que son code fait est de voir si la fonction en question existe déjà, et si elle le fait, il fournit sa propre mise en œuvre de toute façon. Cela semblait … étrange. Je comprends qu'il ajoute des fonctionnalités à l'original, mais encore une fois: je n'utilise pas ces fonctionnalités.
  3. Je voulais un peu de sucre syntaxique supplémentaire pour pouvoir l'appeler comme j'appellerais document.getElementById() ou document.getElementsByTagName() .

Notez que je comptais toujours principalement sur son code. Ses compétences en javascript sont évidemment bien au-delà de la mienne. J'ai essayé de distinguer certaines variables redondantes, mais il en est ainsi.

Dans cet esprit, voici ce que j'ai fini par ( semble fonctionner dans IE6, IE7, Firefox 3 et Chrome voir une nouvelle note à la fin ):

  if (!document.getElementsByClassName) document.getElementsByClassName = function (className) { var classes = className.split(" "); var classesToCheck = ""; var returnElements = []; var match, node, elements; if (document.evaluate) { var xhtmlNamespace = "http://www.w3.org/1999/xhtml"; var namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace:null; for(var j=0, jl=classes.length; j<jl;j+=1) classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]"; try { elements = document.evaluate(".//*" + classesToCheck, document, namespaceResolver, 0, null); } catch(e) { elements = document.evaluate(".//*" + classesToCheck, document, null, 0, null); } while ((match = elements.iterateNext())) returnElements.push(match); } else { classesToCheck = []; elements = (document.all) ? document.all : document.getElementsByTagName("*"); for (var k=0, kl=classes.length; k<kl; k+=1) classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)")); for (var l=0, ll=elements.length; l<ll;l+=1) { node = elements[l]; match = false; for (var m=0, ml=classesToCheck.length; m<ml; m+=1) { match = classesToCheck[m].test(node.className); if (!match) break; } if (match) returnElements.push(node); } } return returnElements; } 

Mettre à jour:
Une nouvelle note à ce sujet. J'ai depuis relu les notes sur la mise en œuvre d'origine, et je comprends maintenant que mon code pourrait tomber dans le cas où le navigateur existant possède sa propre implémentation, car les implémentations par défaut renvoient un nodelist où cela renvoie un tableau. Cela inclut le plus récent firefox et safari, et les navigateurs d'opéra. La plupart du temps, cela ne sera pas important, mais dans certaines situations, il pourrait. Cela explique l'élément n ° 2 de la liste ci-dessus.

Ce que cela signifie, c'est que, bien que mon code fonctionne techniquement partout, il pourrait entraîner un comportement subtilement différent (lecture: difficile à déboguer) dans différents endroits, et ce n'est pas bon. Je devrais réparer cela pour renvoyer un nodelist ou remplacer la méthode fournie pour renvoyer un tableau (c'est ce que l'original a fait). Probablement le premier serait plus simple, mais ce dernier serait mieux .

Cependant, il fonctionne actuellement dans l'environnement intranet local (à peu près tous les IE), donc, pour le moment, je laisserai le correctif comme un exercice pour le lecteur.

Si vous utilisez un cadre, tous ont des sélections utilisant des sélecteurs CSS. Autrement.

 var getElementsByClassName = function(cls, sc){ //Init var elements, i, results = [], curClass; //Default scope is document sc = sc || document; //Get all children of the scope node elements = sc.getElementsByTagName('*'); for( i=0; i < elements.length; i++ ){ curClass = elements[i].getAttribute('class'); if(curClass != null){ curClass = curClass.split(" "); for( j=0; j < curClass.length; j++){ if(curClass[j] === cls){ results.push( elements[i] ); break; } } } } return results; }; 

Je l'ai juste écrit tout à l'heure, juste pour vous. 🙂 N'hésitez pas à utiliser.

Utilisez jquery , il ne peut pas être plus pratique.

$ (".class") ou $ ("theclass"), makeArray () si vous voulez un tableau JS natif

Gardez à l'esprit que au moins FF3 a déjà une implémentation native de getElementsByClassName afaik.

Si vous mettez en œuvre votre propre solution, vous devriez essayer de trouver une solution xpath puisque tous les navigateurs modernes ont un support natif pour xpath.

@ Shog9, @ user28742, @bdukes – Je fais un développement personnalisé dans SharePoint pour une chose modulaire (définition de champ personnalisé) J'espère pouvoir être réutilisé sur de nombreux sites.

Puisque je ne peux pas savoir à l'avance si un site SharePoint donné aura jQuery ou toute autre bibliothèque disponible — Je dois toujours écrire des choses en javascript brut afin que je puisse avoir une certaine confiance que la fonctionnalité que je suis Essayer d'atteindre se tiendra sur ses propres.

Merci à Dmitri pour votre mise en œuvre particulière. Assez court pour mes besoins.

Dans d'autres efforts récents, j'ai dû modifier un magasin de commerce électronique (du choix de mon client) et certaines de mes tentatives d'obtenir que jQuery ait été fraudé en conflit avec les bibliothèques personnalisées qu'ils avaient précédemment manipulées. J'aurais pu être persistant, et j'ai marqué un moyen de mettre en place jQuery dans leur système propriétaire … ou … encore plus vite … n'écris que de bons javascript.

Les libérateurs ne sont TOUJOURS LA MEILLEURE RÉPONSE !!!!!!!!!!!!!!!!

(Et j'aime jQuery plus que ma grand-mère)

Il n'existe pas de classe CSS. CSS a des ensembles de règles et des sélecteurs (y compris le sélecteur de classe).

Voulez-vous dire une classe HTML? La façon habituelle est de faire la boucle de chaque élément du document (en using document.getElementsByTagName('*') (pour une efficacité, utilisez un nom de balise spécifique si vous savez que la classe ne sera appliquée qu'aux éléments d'un certain type) et testez le Propriété className de chacun (notant que la propriété contient une liste séparée par espace de noms de classe, pas un seul nom de classe).

Un certain nombre de bibliothèques (telles que jQuery ou YUI ) ont des fonctions simplement.

Voulez-vous dire un sélecteur CSS? Cela devient plus complexe, et se tourner vers une bibliothèque est presque certainement le bon choix à faire ici. Encore une fois, jQuery ou YUI sont des choix décents.

Si vous voulez faire quelque chose pour tout l'élément avec le même identifiant dans un document. Bien que simple mais quelquefois l'esprit ne donne pas de signaux verts

 var x = document.getElementById(elementid); while(x){ document.removechild(x); x = document.getElementById(elementid); }