Подтвердить что ты не робот

GetElementsByClassName() с двумя классами

Можно ли получить все элементы с классом a или b с помощью getElementsByClassName() только один раз? Я бы предпочел ванильный JavaScript.

4b9b3361

Ответ 1

Вы не можете сделать это с помощью getElementsByClassName() вместо этого используйте querySelectorAll() с селекторами разделенных запятыми.

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

Ответ 2

Чтобы добавить немного больше поддержки, вот версия, совместимая со старыми версиями IE и использующая чистую ваниль 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.
}

Ответ 3

Нет, вы не можете добиться этого только одним вызовом document.getElementsByClassName(). Эта функция возвращает элементы, которые имеют все классы, указанные в первом аргументе, в виде строки, разделенной пробелом.

Существует два возможных решения. Сначала следует использовать document.querySelectorAll(), в котором используются селекторы CSS.

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

Второе решение состоит в том, чтобы дважды вызвать document.getElementsByClassName(), превратить результаты в массивы, используя Array.from() и объединить их с помощью Array.prototype.concat(). Чтобы избежать дублирования (например, когда элемент имеет как a, так и b класс), вам необходимо создать новый Set из этот массив, а затем верните его в массив с помощью Array.from().

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

Смотрите демонстрационную версию ниже:

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>

Ответ 4

Вы можете передать более одного имени класса в getElementsByClassName(), разделив их пробелами:

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

Теперь это отличается от подхода .querySelectorAll(".class1,.class2,.class3") тем, что он применяет конъюнкцию, а не дизъюнкцию — "и" вместо "или". Таким образом,

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

похож на

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

Иногда вам нужен один, иногда вам нужен другой. Это определенно верно, что .querySelectorAll() дает вам гораздо большую гибкость.