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

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

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

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

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

14 ответов

Решение

Ваш 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');

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

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

getElementsByClassName

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

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

getElementById

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

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

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

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

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

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

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>

Как вы можете видеть внутри фрагмента кода, после использования Array.from() Функция, которую вы затем можете манипулировать над каждым элементом.


То же решение с использованием jQuery,

$('.box').css({'background':'green'});
.box {
  width: 50px;
  height: 50px;
  margin: 5px;
  background: blue;
  display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>

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

Метод 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') вернет коллекцию (не массив) из 3 верхних <div>s, так как они соответствуют заданному имени класса.

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

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

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

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

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

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


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

Он используется исключительно с целью простоты и краткости.


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

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


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

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

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


Информация

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

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

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

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

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

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

Возвращает список, похожий на массив.

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

var el = getElementsByClassName("elem");
el = Array.prototype.slice.call(el); //this line
el[0].appendChild(otherElem);  
/*
 * 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

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

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

Супер старое школьное решение:

              [].forEach.call(document.getElementsByClassName('myClass'), function (el) {
            el.style.size = '100px';
        });

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

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

Вопрос

  1. У меня есть код во фрагменте, который имеет document.getElementsByClassName("close")[0], что делает?

  2. Я никогда не видел, чтобы квадратные скобки использовались в getElementsByClassNameс какой целью он используется?

  3. Кроме того, как я могу преобразовать его в jQuery?

Отвечать

  1. Код во фрагменте имеет [0]на самом деле он используется как массив, и поскольку он равен 0, он относится к первому использованию назначенного класса.

  2. То же самое выше.

  3. Я действительно не мог этого сделать, и никто не ответил на это. В той части кода, которая относится к event. targetя не могу использовать $("#myModal")вместо document.getElementById("myModal"), я думаю, они должны быть эквивалентны, но в этом случае замена стандартной jQuery-формы не даст нужного эффекта.

          window.onclick = function(event) {
      if (event.target == modal) {
        modal.style.display = "none";
      }
    }

Обновить

Кажется, я не могу удалить свой вопрос, и люди им недовольны, я действительно не знаю, что мне делать.

Ответ на конкретный случай Дрензи...

Вы можете создать функцию, которая будет работать для любого изwordэлементы и передайте номер того, который вы хотите преобразовать, например:

// Binds `wordButtons` to an (array-like) HTMLCollection of buttons
const wordButtons = document.getElementsByClassName("word");

// Applies the `slantWord` function to the first word button
slantWord(1);

// Defines the `slantWord` function
function slantWord(wordNumber) {
  const index = wordNumber - 1; // Collection index is zero-based
  wordButtons[index].style.transform = "rotate(7deg)"; // Transforms the specified button
}
<div class="wordGameContainer">
  <button class="word word1">WORD 1</button>
  <button class="word word2">WORD 2</button>
  <button class="word word3">WORD 3</button>
  <button class="word word4">WORD 4</button>
</div>

<div>
  <button onclick="moveWord()" class="playButton">PLAY</button>
</div>

Это также сработает:

      for (let el of document.getElementsByClassName('myElement')) {
    el.style.color = 'red';
}

Обязательно заверните все вышесказанное в window.onload функция для безопасности, если некоторые элементы появляются после завершения загрузки окна:

      window.onload = function() {
    for (let el of document.getElementsByClassName('myElement')) {
        el.style.color = 'red';
    }
}

Скрыть элемент только по имени класса.

document.getElementsByClassName(targetElement)[0].style.display = 'нет';

Другие вопросы по тегам