에서 모든 요소의 id를 가져 오려고합니다 HTMLCollectionOf
. 다음 코드를 작성했습니다.
var list = document.getElementsByClassName("events");
console.log(list[0].id);
for (key in list) {
console.log(key.id);
}
그러나 콘솔에서 다음과 같은 결과가 나타납니다.
event1
undefined
내가 기대 한 것이 아닙니다. 왜 두 번째 콘솔 출력 undefined
이지만 첫 번째 콘솔 출력은 event1
무엇입니까?
답변
원래 질문에 대한 답을 for/in
잘못 사용하고 있습니다 . 귀하의 코드 key
에서 색인입니다. 따라서 의사 배열에서 값을 얻으려면 수행해야 list[key]
하고 ID를 가져와야 list[key].id
합니다. 그러나 for/in
처음부터이 작업을 수행해서는 안됩니다 .
요약 (2018 년 12 월 추가)
for/in
nodeList 또는 HTMLCollection을 반복하는 데 사용하지 마십시오 . 이를 피하는 이유는 다음과 같습니다.
최신 브라우저의 모든 최신 버전 (사파리, 파이어 폭스, 크롬, 에지) 모든 지원 for/of
DOM에 대한 반복은 나열 nodeList
하거나 HTMLCollection
.
예를 들면 다음과 같습니다.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
오래된 브라우저 (IE와 같은 것들 포함)를 포함 시키려면 다음과 같이 작동합니다.
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
왜 사용하지 말아야하는지에 대한 설명 for/in
for/in
객체의 속성을 반복하기위한 것입니다. 즉, 객체의 모든 반복 가능한 속성을 반환합니다. 배열 (배열 요소 또는 의사 배열 요소 반환)에 대해 작동하는 것처럼 보일 수 있지만 배열과 같은 요소에서 예상하지 않은 객체의 다른 속성을 반환 할 수도 있습니다. 그리고 객체 HTMLCollection
또는 nodeList
객체 모두 for/in
반복 과 함께 반환되는 다른 속성을 가질 수 있는 것을 추측하십시오 . 방금 Chrome에서 이것을 시도하고 반복하는 방식으로 반복하면 목록의 항목 (색인 0, 1, 2 등)이 검색되지만 length
및 item
속성 도 검색 됩니다. for/in
반복은 단순히 HTMLCollection 작동하지 않습니다.
로 HTMLCollection을 반복 할 수없는 이유는 http://jsfiddle.net/jfriend00/FzZ2H/ 를 참조하십시오 for/in
.
Firefox에서는 for/in
반복시 다음 항목 (객체의 반복 가능한 모든 속성)이 반환됩니다.
0
1
2
item
namedItem
@@iterator
length
바라 건데, 지금 당신은 당신이 사용하고자하는 이유를 볼 수 있습니다 for (var i = 0; i < list.length; i++)
당신은 그냥 얻을 수 있도록 대신에 0
, 1
그리고 2
당신의 반복이다.
다음은 2015-2018 기간 동안 브라우저가 어떻게 진화했는지에 대한 진화입니다. 위에 설명 된 옵션을 사용할 수 있으므로 최신 브라우저에서는이 중 어느 것도 필요하지 않습니다.
2015 년 ES6 업데이트
ES6 Array.from()
에는 배열과 같은 구조를 실제 배열로 변환하는 기능 이 추가되었습니다 . 이를 통해 다음과 같이 직접 목록을 열거 할 수 있습니다.
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
실무 데모 (2016 년 4 월 기준 Firefox, Chrome 및 Edge) : https://jsfiddle.net/jfriend00/8ar4xn2s/
2016 년 ES6 업데이트
이제 코드에 이것을 추가하여 a NodeList
및 a 와 함께 ES6 for / of 구문을 사용할 수 있습니다 HTMLCollection
.
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
그런 다음 다음을 수행 할 수 있습니다.
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
현재 버전의 Chrome, Firefox 및 Edge에서 작동합니다. 이는 Array 반복자를 NodeList 및 HTMLCollection 프로토 타입 모두에 연결하여 반복 할 때 Array 반복자를 사용하여 반복하기 때문에 작동합니다.
실무 데모 : http://jsfiddle.net/jfriend00/joy06u4e/ .
2016 년 12 월 ES6의 두 번째 업데이트
2016 년 12 월 현재 Symbol.iterator
Chrome v54 및 Firefox v50이 기본적으로 지원되므로 아래 코드는 저절로 작동합니다. 아직 Edge 용으로 제공되지 않습니다.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
실무 데모 (Chrome 및 Firefox) : http://jsfiddle.net/jfriend00/3ddpz8sp/
2017 년 12 월 ES6의 세 번째 업데이트
12 월 2017,이 기능 A의 가장자리 41.16299.15.0의 작품 nodeList
에서와 같은 document.querySelectorAll()
,하지만 아닌 HTMLCollection
처럼 document.getElementsByClassName()
당신이 그래서 수동을 위해 가장자리에서 사용하는 반복자를 할당합니다 HTMLCollection
. 하나의 컬렉션 유형을 수정했지만 다른 유형은 수정하지 않는 것은 완전히 신비입니다. 그러나 현재 최신 버전의 Edge에서는 document.querySelectorAll()
ES6 for/of
구문으로 결과를 사용할 수 있습니다 .
이 모두를 테스트 그래서 나는 또한 jsFiddle 위가 업데이트 HTMLCollection
와 nodeList
별도로하고 jsFiddle 자체 출력을 캡처합니다.
2018 년 3 월 ES6 용 네 번째 업데이트
mesqueeeb 당, Symbol.iterator
지원이 내장 된 사파리로도 사용할 수 있도록 for (let item of list)
중 하나에 대해 document.getElementsByClassName()
나 document.querySelectorAll()
.
2018 년 4 월 ES6의 다섯 번째 업데이트
분명히 2018 년 가을에 HTMLCollection
with 를 반복하는 지원 for/of
이 Edge 18에 제공 될 것입니다.
2018 년 11 월 ES6 여섯 번째 업데이트
Microsoft Edge v18 (2018 년 가을 Windows 업데이트에 포함)을 사용하면 Edge에서 for / of를 사용하여 HTMLCollection과 NodeList를 모두 반복 할 수 있습니다.
따라서 모든 최신 브라우저에는 for/of
HTMLCollection 및 NodeList 객체의 반복을 기본적으로 지원 합니다.
답변
for
/ in
on NodeList
또는 HTMLCollection
s를 사용할 수 없습니다 . 그러나 Array.prototype
메소드를 .call()
전달하고 NodeList
또는 HTMLCollection
로 전달 하는 한 일부 메소드 를 사용할 수 있습니다 this
.
따라서 jfriend00의 for
루프에 대한 대안으로 다음을 고려하십시오 .
var list= document.getElementsByClassName("events");
[].forEach.call(list, function(el) {
console.log(el.id);
});
이 기술을 다루는 MDN에 대한 좋은 기사 가 있습니다. 브라우저 호환성에 대한 경고는 다음과 같습니다.
[…] (A와 같은 호스트 개체를 전달
NodeList
로)
this
(예 : 기본 방법은forEach
) 모든 브라우저에서 작동이 보장되지는 않으며 일부에서 실패하는 것으로 알려져있다.
따라서이 방법은 편리하지만 for
루프는 브라우저와 가장 호환되는 솔루션 일 수 있습니다.
업데이트 (2014 년 8 월 30 일) : 결국 ES6 for
/of
!
var list = document.getElementsByClassName("events");
for (const el of list)
console.log(el.id);
최신 버전의 Chrome 및 Firefox에서 이미 지원됩니다.
답변
ES6에서, 당신이 뭔가를 같이 할 수있는 [...collection]
, 또는 Array.from(collection)
,
let someCollection = document.querySelectorAll(someSelector)
[...someCollection].forEach(someFn)
//or
Array.from(collection).forEach(someFn)
예 :-
navDoms = document.getElementsByClassName('nav-container');
Array.from(navDoms).forEach(function(navDom){
//implement function operations
});
답변
이 두 줄을 추가 할 수 있습니다.
HTMLCollection.prototype.forEach = Array.prototype.forEach;
NodeList.prototype.forEach = Array.prototype.forEach;
HTMLCollection 은 getElementsByClassName 및 getElementsByTagName에 의해 리턴됩니다.
querySelectorAll에 의해 NodeList 가 리턴됩니다.
이와 같이 당신은 forEach를 할 수 있습니다 :
var selections = document.getElementsByClassName('myClass');
/* alternative :
var selections = document.querySelectorAll('.myClass');
*/
selections.forEach(function(element, i){
//do your stuffs
});
답변
IE 11 및 Firefox 49 에서 forEach를 사용하는 데 문제가 있습니다.
이 같은 해결 방법을 찾았습니다
Array.prototype.slice.call(document.getElementsByClassName("events")).forEach(function (key) {
console.log(key.id);
}
답변
대안 Array.from
은 사용하는 것입니다Array.prototype.forEach.call
각각:
Array.prototype.forEach.call(htmlCollection, i => { console.log(i) });
지도: Array.prototype.map.call(htmlCollection, i => { console.log(i) });
요법 …
답변
for
IE9 이상인 경우 es6 기능을 사용하여 루핑 을 피할 이유가 없습니다 .
ES5에는 두 가지 좋은 옵션이 있습니다. 첫째, 당신은 “대출”은 수 Array
의 forEach
로 에반 언급 .
그러나 더 나은 …
를 사용 Object.keys()
하면 자동으로 “속성을 소유”하는 필터 가 있습니다 forEach
.
즉, Object.keys
본질적으로 a를 for... in
사용하는 것과 동일 HasOwnProperty
하지만 훨씬 더 부드럽습니다.
var eventNodes = document.getElementsByClassName("events");
Object.keys(eventNodes).forEach(function (key) {
console.log(eventNodes[key].id);
});