Ist es möglich , alle Elemente mit Klasse zu erhalten a oder b mit getElementsByClassName()nur einmal? Ich würde Vanille JavaScript bevorzugen.
Ist es möglich , alle Elemente mit Klasse zu erhalten a oder b mit getElementsByClassName()nur einmal? Ich würde Vanille JavaScript bevorzugen.
Antworten:
Sie können dies nicht mit der getElementsByClassName()Methode tun , sondern verwenden Sie die querySelectorAll()Methode mit durch Kommas getrennten Klassenselektoren.
document.querySelectorAll('.a,.b')
.a,.bnicht nur zwei CSS2-Selektoren?
IE <= 7:);)
Sie können mehr als einen Klassennamen übergeben, getElementsByClassName()indem Sie sie durch Leerzeichen trennen:
var elems = document.getElementsByClassName("class1 class2 class3");
Dies unterscheidet sich vom .querySelectorAll(".class1,.class2,.class3")Ansatz darin, dass eine Konjunktion angewendet wird , keine Disjunktion - "und" anstelle von "oder". So
var elems = document.getElementsByClassName("class1 class2 class3");
ist wie
var elems = document.querySelectorAll(".class1.class2.class3");
Manchmal willst du eins, manchmal willst du das andere. Es ist definitiv wahr, dass .querySelectorAll()Sie viel mehr Flexibilität geben.
Nein, das können Sie nicht mit nur einem document.getElementsByClassName()Anruf erreichen. Diese Funktion gibt Elemente zurück, bei denen alle im ersten Argument angegebenen Klassen als durch Leerzeichen getrennte Zeichenfolge vorliegen.
Es gibt zwei mögliche Lösungen. Zunächst wird document.querySelectorAll()stattdessen CSS-Selektoren verwendet.
document.querySelectorAll(".a, .b")
Die zweite Lösung besteht darin, document.getElementsByClassName()zweimal aufzurufen , die Ergebnisse mit Arrays umzuwandeln Array.from()und sie mit zusammenzuführen Array.prototype.concat(). Um Duplikate zu vermeiden (z. B. wenn das Element sowohl a als auch eine bKlasse enthält), müssen Sie aus diesem Array einen neuen Satz erstellen und ihn dann mithilfe von wieder in das Array zurücksetzen Array.from().
const classA = Array.from(document.getElementsByClassName("a"))
,classB = Array.from(document.getElementsByClassName("b"))
,result = Array.from(new Set(classA.concat(classB)))
Siehe Demo unten:
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>
Beachten Sie, dass die erste Lösung ein Array-ähnliches NodeListObjekt ergibt, während die zweite nur ein Array ergibt.
document.querySelectorAll()(da es nicht Teil von ECMAScript, sondern von Web-APIs ist). Wenn Sie Ihren Code mit Babel kompilieren, funktioniert die zweite Lösung in allen Browsern. Und ehrlich gesagt habe ich die zweite Lösung eher zum Spaß als als echte Lösung geschrieben.
Um ein bisschen mehr Unterstützung hinzuzufügen, hier ist eine Version, die mit älteren Versionen von IE kompatibel ist und reine Vanille-JS verwendet:
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.
}
much slowerBrowser abgezielt wird. Die Leistung ist in dieser Situation von entscheidender Bedeutung. Ich empfehle, mehrere Aufrufe zu verwenden Element.getElementsByClassNameund ein verkettetes Array der Ergebnisse zu verwenden.
class="a b c"bei der Suche mit nicht funktioniert 'a c'.