38 votes

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

Quel est le meilleur moyen d'obtenir un tableau de tous les éléments dans un document html avec une classe CSS spécifique en utilisant javascript ?

Aucun framework javascript comme jQuery autorisé ici pour le moment, et je pourrais parcourir tous les éléments et les vérifier manuellement moi-même. J'espère quelque chose de un peu plus élégant.

38voto

Chris MacDonald Points 3261

1) Obtenir tous les éléments dans le document (document.getElementsByTagName('*'))
2) Faire correspondre une expression régulière sur l'attribut className de chaque élément

36voto

Shog9 Points 82052

La réponse ci-dessous a maintenant près de quatre ans, il est donc bon de noter que la prise en charge native par le navigateur pour getElementsByClassName() s'est considérablement améliorée. Mais si vous devez prendre en charge d'anciens navigateurs, alors…

Utilisez-en un qui a déjà été écrit. La plupart des grandes bibliothèques JS en incluent une sous une forme ou une autre, mais si vous n'en utilisez aucune, 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 boguée pour justifier l'écriture de votre propre implémentation à ce stade.

7voto

bdukes Points 54833

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

MISE À JOUR: L'implémentation mentionnée par @Shog9 est probablement meilleure que celle ci-dessus.

6voto

Joel Coehoorn Points 190579

Juste pour faire un suivi, j'ai basé mon code sur l'implémentation de Robert Nyman publiée par Shog9, mais je me suis un peu éloigné de sa version exacte, pour trois raisons:

  1. Il vous permettait de sélectionner un élément racine et un type de balise pour filtrer vos résultats. Je n'ai pas besoin de cette fonctionnalité et en la supprimant, j'ai pu simplifier considérablement le code.
  2. La première chose que son code fait est de vérifier si la fonction en question existe déjà, et si c'est le cas, il fournit quand même sa propre implémentation. Cela semblait juste... étrange. Je comprends qu'il ajoutait des fonctionnalités à l'original, mais encore une fois: je n'utilise pas ces fonctionnalités.
  3. Je voulais ajouter un peu de sucre syntaxique supplémentaire- pour pouvoir l'appeler comme je ferais avec document.getElementById() ou document.getElementsByTagName().

Remarquez que je me suis quand même principalement basé sur son code. Ses compétences en javascript sont évidemment bien au-dessus des miennes. J'ai essayé d'éliminer certaines variables redondantes, mais c'est à peu près tout.

Avec cela en tête, voici sur quoi je suis tombé (semble fonctionner dans IE6, IE7, Firefox 3 et Chrome voir la 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

`

Mise à jour:
Une nouvelle note à ce sujet. J'ai depuis relu les notes sur l'implémentation originale, et je comprends maintenant que mon code pourrait poser problème dans le cas où le navigateur existant a sa propre implémentation, car les implémentations par défaut renvoient un nœud NodeList là où cela renvoie un tableau. Cela inclut les navigateurs plus récents comme Firefox et Safari, et Opera. La plupart du temps, cela n'aura pas d'importance, mais dans certaines situations, cela pourrait. Cela explique le point #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 légèrement différent (comprenez: difficile à déboguer) à différents endroits, et ce n'est pas bon. Je devrais résoudre ce problème pour renvoyer également un nœud NodeList ou pour remplacer la méthode fournie pour renvoyer un tableau (ce que faisait l'original). Probablement la première option serait plus simple, mais la seconde serait meilleure.

Cependant, cela fonctionne actuellement dans l'environnement intranet local (pratiquement tout IE), donc pour le moment je laisse la correction comme un exercice pour le lecteur.

`

5voto

Dmitri Farkov Points 3743

Si vous utilisez un framework, ils ont tous des sélections utilisant des sélecteurs CSS. Sinon.

var getElementsByClassName = function(cls, sc){
    //Init
    var elements, i, results = [], curClass;  

    //La portée par défaut est le document
    sc = sc || document;

    //Obtenir tous les enfants du nœud de portée
    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 viens de l'écrire pour vous. :) N'hésitez pas à l'utiliser.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X