Почему я могу использовать каждый из списков NodeList, но не все? - PullRequest
3 голосов
/ 15 марта 2019

Поскольку я отвечал на вопросы на этом сайте, я начал использовать .forEach() намного больше.Я также начал использовать document.getElementsByClassName() или document.querySelectorAll() и многое другое.

Недавно я заметил, что иногда .forEach() работает, а иногда нет.После небольшого исследования я обнаружил, что вы не можете .forEach() через NodeList.Затем я пошел на этот ответ и обнаружил, что вы можете .forEach() в NodeList.

Примечание: Я также добавил ниже 2 фрагмента, в которых .forEach() работает и не работает.Кажется, работает для document.querySelectorAll(), но не document.getElementsByClassName(), но почему?Разве они оба не возвращают NodeList?

TL; DR: Почему я могу .forEach() на некоторых NodeLists, но не на всех?

.forEach() работает над этим фрагментом.

let text = document.querySelectorAll(".text");

console.log(typeof text);
text.forEach(e => {
  console.log(e);
});
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>

.forEach() не работает с этим фрагментом.

let text = document.getElementsByClassName("text");

console.log(typeof text);
text.forEach(e => {
  console.log(e);
});
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>

Ответы [ 3 ]

2 голосов
/ 15 марта 2019

Это происходит потому, что getElementsByClassName возвращает не массив, а HTMLCollection. Это array-like объект, как описано в документации.

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

const list = document.getElementsByClassName('text');
const matches = Array.prototype.forEach.call(list, (el) => console.log(el));

Я добавил фрагмент, чтобы прояснить, что это прекрасно работает:

const list = document.getElementsByClassName('text');
const matches = Array.prototype.forEach.call(list, (el) => console.log(el));
  <div class="text"></div>
  <div class="text"></div>
  <div class="text"></div>
  <div class="text"></div>

Ссылки:

  1. https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection

  2. https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName

2 голосов
/ 15 марта 2019

Это потому, что querySelectorAll возвращает NodeList, а getElementsByClassName возвращает HTMLCollection:

let querySelector = document.querySelectorAll(".text");
let className = document.getElementsByClassName("text");
console.log(querySelector.constructor.name);
console.log(className.constructor.name);
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>

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

let text = Array.from(document.getElementsByClassName("text"));

text.forEach(e => {
  console.log(e);
});
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>
<div class="text">Text</div>
1 голос
/ 15 марта 2019

getElementsByClassName возвращает HTMLCollection, для которого нет метода forEach.

let text1 = document.querySelectorAll(".text");
let text2 = document.getElementsByClassName("text");

console.log(text1.forEach);
console.log(text2.forEach);
<div class="text">Text</div>

Ссылка: https://developer.mozilla.org/ko/docs/Web/API/Document/getElementsByClassName

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...