Что возвращают методы querySelectorAll и getElementsBy *?

Do getElementsByClassName (и подобные функции, такие как getElementsByTagName и querySelectorAll) работают так же, как getElementById, или они возвращают массив элементов?

Я спрашиваю, потому что я пытаюсь изменить стиль всех элементов, используя getElementsByClassName. См. Ниже.

//doesn't work
document.getElementsByClassName('myElement').style.size = '100px';

//works
document.getElementById('myIdElement').style.size = '100px';

Ответ 1

Ваш код getElementById() работает, поскольку идентификаторы должны быть уникальными, и поэтому функция всегда возвращает ровно один элемент (или null, если ни один не найден).

Однако getElementsByClassName(), querySelectorAll(), и другие методы getElementsBy* возвращают массив-подобный набор элементов. Итерации над ним, как и с реальным массивом:

var elems = document.getElementsByClassName('myElement');
for(var i = 0; i < elems.length; i++) {
    elems[i].style.size = '100px';
}

Если вы предпочитаете что-то более короткое, рассмотрите возможность использования jQuery:

$('.myElement').css('size', '100px');

Ответ 2

Вы используете массив в качестве объекта, разница между getElementbyId и getElementsByClassName заключается в том, что:

  • getElementbyId вернет вам объект.
  • getElementsByClassName вернет вам массив.

getElementsByClassName

Метод getElementsByClassName(classNames) принимает строку, содержащую неупорядоченный набор уникальных разделенных пробелами токенов, представляющих классы. При вызове метод должен возвращать живой объект NodeList содержащий все элементы в документе, которые имеют все классы, указанные в этом аргументе, получив классы, разбив строку на пробелы. Если в аргументе не указаны токены, метод должен вернуть пустой NodeList.

https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#getelementsbyclassname

getElementById

Метод getElementById() обращается к первому элементу с указанным идентификатором.

http://www.w3schools.com/jsref/met_doc_getelementbyid.asp

в вашем коде строки:

1- document.getElementsByClassName('myElement'). Style.size = '100px';

НЕ будет работать должным образом, потому что getElementByClassName вернет массив, а массив НЕ будет иметь свойства style, вы можете получить доступ к каждому element, просматривая их.

Поэтому функция getElementById работает для вас, эта функция будет возвращать прямой объект. Поэтому вы сможете получить доступ к свойству style.

Ответ 3

Следующее описание взято с этой страницы:

Метод getElementsByClassName() возвращает коллекцию всех элементов в документе с указанным именем класса в виде объекта NodeList.

Объект NodeList представляет коллекцию узлов. Доступ к узлам осуществляется по номерам индексов. Индекс начинается с 0.

Совет: вы можете использовать свойство length объекта NodeList, чтобы определить количество элементов с указанным именем класса, затем вы можете просмотреть все элементы и извлечь нужную информацию.

Таким образом, в качестве параметра getElementsByClassName будет принимать имя класса.

Если это ваше тело HTML:

<div id="first" class="menuItem"></div>
<div id="second" class="menuItem"></div>
<div id="third" class="menuItem"></div>
<div id="footer"></div>

тогда var menuItems = document.getElementsByClassName('menuItem') вернет коллекцию (не массив) из трех верхних <div>, поскольку они соответствуют заданному имени класса.

Затем вы можете перебрать эту коллекцию узлов (в данном случае <div>) с помощью:

for (var menuItemIndex = 0 ; menuItems.length ; menuItemIndex ++) {
   var currentMenuItem = menuItems[menuItemIndex];
   // do stuff with currentMenuItem as a node.
}

Пожалуйста, обратитесь к этому сообщению для получения дополнительной информации о различиях между элементами и узлами.

Ответ 4

ES6 предоставляет Array.from(), который создает новый экземпляр Array из массива или повторяемого объекта.

let boxes = document.getElementsByClassName('box');

Array.from(boxes).forEach(v => v.style.background = 'green');
console.log(Array.from(boxes));
.box {
  width: 50px;
  height: 50px;
  margin: 5px;
  background: blue;
  display: inline-block;
}
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>

Ответ 5

Другими словами

  • document.querySelector() выбирает только первый элемент указанного селектора. Так что это не выплевывает массив, это единственное значение. Аналогично document.getElementById() который выбирает только ID-элементы, поскольку идентификаторы должны быть уникальными.

  • document.querySelectorAll() выделяет все элементы с указанным селектором и возвращает их в массиве. Аналогично document.getElementsByClassName() для классов и тегов document.getElementsByTagName().


Зачем использовать querySelector?

Это использовалось только с единственной целью легкости и краткости.


Зачем использовать getElement/sBy? *

Быстрее производительность.


Почему эта разница в производительности?

Оба способа выбора имеют целью создание NodeList для дальнейшего использования. querySelectors генерирует статический NodeList с селекторами, поэтому он должен быть сначала создан с нуля.
getElement/sBy * немедленно адаптирует существующий действующий NodeList текущего DOM.

Итак, когда использовать какой метод это до вас/вашего проекта/вашего устройства.


Информация

Демо всех методов
Документация по NodeList
Тест производительности

Ответ 6

Он возвращает список, подобный массиву.

Вы делаете этот массив как пример

var el = getElementsByClassName("elem");
el = Array.prototype.slice.call(el); //this line
el[0].appendChild(otherElem);  

Ответ 7

Вы можете получить один элемент, запустив

document.querySelector('.myElement').style.size = '100px';

но он будет работать для первого элемента с классом .myElement.

Если вы хотите применить это для всех элементов класса, я предлагаю вам использовать

document.querySelectorAll('.myElement').forEach(function(element) {
    element.style.size = '100px';
});

Ответ 8

/*
 * To hide all elements with the same class, 
 * use looping to reach each element with that class. 
 * In this case, looping is done recursively
 */

const hideAll = (className, i=0) => {
if(!document.getElementsByClassName(className)[i]){ //exits the loop when element of that id does not exist
  return; 
}

document.getElementsByClassName(className)[i].style.visibility = 'hidden'; //hide element
return hideAll(className, i+1) //loop for the next element
}

hideAll('appBanner') //the function call requires the class name

Ответ 9

С ES5 + (любой просматриваемый в настоящее время - 2017) вы сможете сделать

[].forEach.call(document.getElementsByClassName('answer'), function(el) {
    el.style.color= 'red';
});