[javascript] JS : Array.forEach를 사용하여 getElementsByClassName의 결과를 반복

일부 DOM 요소를 반복하고 싶습니다.이 작업을 수행하고 있습니다.

document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
  //do stuff
});

하지만 오류가 발생합니다.

document.getElementsByClassName ( “myclass”). forEach는 함수가 아닙니다

나는 모두 알고, 그래서 나는 파이어 폭스 3를 사용하고 getElementsByClassName그리고 Array.forEach존재한다. 이것은 잘 작동합니다.

[2, 5, 9].forEach( function(element, index, array) {
  //do stuff
});

getElementsByClassName배열 의 결과 입니까? 그렇지 않다면 무엇입니까?



답변

제 바와 같이 DOM4에 지정된 , 그것은이다 HTMLCollection(적어도, 최신 브라우저에서. 이전 브라우저는 반환 NodeList).

모든 최신 브라우저 (다른 IE <= 8)에서 Array의 forEach메서드를 호출 하여 요소 목록 ( HTMLCollection또는 NodeList)을 this값 으로 전달할 수 있습니다 .

var els = document.getElementsByClassName("myclass");

Array.prototype.forEach.call(els, function(el) {
    // Do stuff here
    console.log(el.tagName);
});

// Or
[].forEach.call(els, function (el) {...});

ES6을 사용할 수있는 좋은 위치에 있다면 (예 : Internet Explorer를 안전하게 무시하거나 ES5 트랜스 파일러를 사용하는 경우) 다음을 사용할 수 있습니다 Array.from.

Array.from(els).forEach((el) => {
    // Do stuff here
    console.log(el.tagName);
});


답변

Array.from컬렉션을 배열로 변환 하는 데 사용할 수 있습니다 Array.prototype.forEach.call.

Array.from(document.getElementsByClassName("myclass")).forEach(
    function(element, index, array) {
        // do stuff
    }
);

을 지원하지 않는 이전 브라우저에서는 Array.fromBabel과 같은 것을 사용해야합니다.


ES6는 또한 다음 구문을 추가합니다.

[...document.getElementsByClassName("myclass")].forEach(
    (element, index, array) => {
        // do stuff
    }
);

...배열 자체는 배열 자체뿐만 아니라 모든 배열과 유사한 객체에서 작동하여 나머지 오래된 구문 구문을 사용하여 값에서 배열을 구성합니다.


대체 함수 querySelectorAll(일부 getElementsByClassName사용 하지 않음)는 forEach기본적으로 존재 map하거나 다른 메소드와 같 거나 filter누락 된 콜렉션을 리턴하지만 이 구문은 여전히 ​​유용합니다.

[...document.querySelectorAll(".myclass")].map(
    (element, index, array) => {
        // do stuff
    }
);

[...document.querySelectorAll(".myclass")].map(element => element.innerHTML);


답변

또는 NodeListquerySelectorAll 를 반환 하는 것을 사용할 수 있습니다 .

document.querySelectorAll('.myclass').forEach(...)

최신 브라우저에서 지원 (IE를 제외하고 Edge 포함) :
querySelectorAll NodeList.prototype.forEach ()를 사용할 수 있습니까

MDN : Document.querySelectorAll ()


답변

편집 : 새로운 버전의 HTML에서 반환 유형이 변경되었지만 (팀 다운의 업데이트 된 답변 참조) 아래 코드는 여전히 작동합니다.

다른 사람들이 말했듯이, NodeList입니다. 다음은 시도해 볼 수있는 완전하고 효과적인 예입니다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <script>
            function findTheOddOnes()
            {
                var theOddOnes = document.getElementsByClassName("odd");
                for(var i=0; i<theOddOnes.length; i++)
                {
                    alert(theOddOnes[i].innerHTML);
                }
            }
        </script>
    </head>
    <body>
        <h1>getElementsByClassName Test</h1>
        <p class="odd">This is an odd para.</p>
        <p>This is an even para.</p>
        <p class="odd">This one is also odd.</p>
        <p>This one is not odd.</p>
        <form>
            <input type="button" value="Find the odd ones..." onclick="findTheOddOnes()">
        </form>
    </body>
</html>

이것은 Win 7의 IE 9, FF 5, Safari 5 및 Chrome 12에서 작동합니다.


답변

의 결과 getElementsByClassName()는 Array가 아니라 array-like object 입니다. 구체적으로는라고 HTMLCollection혼동하지 NodeList( 갖는 그 자신의 forEach()메소드 ).

ES2015에서 Array.prototype.forEach()아직 언급되지 않은 배열과 같은 객체를 변환하는 간단한 방법 은 스프레드 연산자 또는 스프레드 구문 을 사용하는 것입니다 .

const elementsArray = document.getElementsByClassName('myclass');

[...elementsArray].forEach((element, index, array) => {
    // do something
});


답변

getElementsByClassName의 결과가 배열입니까?

아니

그렇지 않다면 무엇입니까?

여러 요소를 반환하는 모든 DOM 메소드와 마찬가지로 NodeList입니다 ( https://developer.mozilla.org/en/DOM/document.getElementsByClassName 참조).


답변

이미 말했듯이, getElementsByClassName반환 HTMLCollection 으로 정의된다,

[Exposed=Window]
interface HTMLCollection {
  readonly attribute unsigned long length;
  getter Element? item(unsigned long index);
  getter Element? namedItem(DOMString name);
};

이전에는 일부 브라우저가 대신 NodeList 를 반환했습니다 .

[Exposed=Window]
interface NodeList {
  getter Node? item(unsigned long index);
  readonly attribute unsigned long length;
  iterable<Node>;
};

DOM4는 이제 NodeList 를 반복 가능한 것으로 정의하기 때문에 차이점이 중요합니다 .

Web IDL 초안 에 따르면

반복 가능한 것으로 선언 된 인터페이스를 구현하는 객체는 일련의 값을 얻기 위해 반복되는 지원을 제공합니다.

참고 : ECMAScript 언어 바인딩에서 반복 가능한 인터페이스인터페이스 프로토 타입 객체 에 “항목”,“forEach”,“키”,“값”및
@@ iterator 속성이 있습니다 .

즉,를 사용하려는 경우 와 같이 NodeListforEach 를 반환하는 DOM 메소드를 사용할 수 있습니다 .querySelectorAll

document.querySelectorAll(".myclass").forEach(function(element, index, array) {
  // do stuff
});

아직 널리 지원되지는 않습니다. Node.childNodes의 각 메소드를 참조하십시오 .