web-dev-qa-db-fra.com

getElementsByClassName () avec deux classes

Est-il possible d'obtenir tous les éléments avec la classe aob en utilisant getElementsByClassName() une seule fois? Je préférerais JavaScript à la vanille.

55

Vous ne pouvez pas le faire avec la méthode getElementsByClassName()querySelectorAll() ) = avec des sélecteurs de classe séparés par des virgules.

document.querySelectorAll('.a,.b')
93
Pranav C Balan

Juste pour ajouter un peu plus de support, voici une version compatible avec les anciennes versions de IE et utilisant Pure Vanilla js:

function getElementsByClassNameOr(root, classNameString) // classNameString like '.a, .b' don't forget the comma separator
 {
    var arr = [],
    rx = new RegExp('(^|[ \n\r\t\f])' + classNameString + '([ \n\r\t\f]|$)'),
    elements = root.getElementsByTagName("*");

    var elem;

    for (i=0 ; i < elements.length ; i++) {
        elem = elements[i];
        if (rx.test(elem.className)) {
            arr.Push(elem);
        }

    }

    return arr; // will contain all the elements that have one of the classes in ClassNameString, root can be document or a div.
}
6
zoubida13

Vous pouvez passer plus d'un nom de classe à getElementsByClassName() en les séparant par des espaces:

var elems = document.getElementsByClassName("class1 class2 class3");

Maintenant, ceci diffère de l'approche .querySelectorAll(".class1,.class2,.class3") en ce qu'il applique une conjonction, pas une disjonction - "et" au lieu de "ou". Ainsi

var elems = document.getElementsByClassName("class1 class2 class3");

est comme

var elems = document.querySelectorAll(".class1.class2.class3");

Parfois, vous en voulez un, parfois, vous voulez l'autre. Il est bien vrai que .querySelectorAll() vous donne beaucoup plus de flexibilité.

6
Pointy

Non, vous ne pouvez pas y arriver avec un seul appel document.getElementsByClassName() . Cette fonction retourne les éléments qui ont la totalité des classes spécifiées dans le premier argument sous forme de chaîne séparée par des espaces.

Il y a deux solutions possibles. La première consiste à utiliser document.querySelectorAll() , qui utilise des sélecteurs CSS.

document.querySelectorAll(".a, .b")

La deuxième solution consiste à appeler document.getElementsByClassName() à deux reprises, à transformer les résultats en tableaux à l'aide de Array.from() et à les fusionner à l'aide de Array.prototype.concat() . Pour éviter les doublons (par exemple lorsque l’élément a les deux a et b class), vous devez créer un nouveau Définissez à partir de ce tableau, puis reconvertissez-le en tableau à l'aide de Array.from().

const classA = Array.from(document.getElementsByClassName("a"))
     ,classB = Array.from(document.getElementsByClassName("b"))
     ,result = Array.from(new Set(classA.concat(classB)))

Voir la démo ci-dessous:

console.log("first solution", document.querySelectorAll(".a, .b"))

const classA = Array.from(document.getElementsByClassName("a"))
     ,classB = Array.from(document.getElementsByClassName("b"))
     ,result = Array.from(new Set(classA.concat(classB)))

console.log("second solution", result)
<div class="a"></div>
<div class="b"></div>
<div class="a b"></div>
<div class="c"></div>

Notez que la première solution donne un objet de type tableau NodeList , alors que la seconde ne donne qu'un tableau.

6