Javascript에서 NodeList를 배열로 변환하는 가장 좋은 방법은 무엇입니까?


82

DOM 메서드 document.querySelectorAll()(및 기타 몇 가지)는 NodeList.

예를 들어를 사용하여 목록 forEach()에서 작업 NodeList하려면 먼저를 Array.

을 변환하는 가장 좋은 방법은 무엇입니까 NodeList로는 Array?


1
querySelectorAll ()의 반환 값은 기술적으로 NodeList라고합니다.
jfriend00 2011 년

MDM "= document.querySelectorAll 요소리스트 (선택기);"
cc young

1
elementList는 변수 이름입니다. 동일한 페이지에서 반환 값의 유형이 NodeList 인 방법을 설명합니다.
jfriend00

정정 해 주셔서 감사합니다-문제가 해결되었습니다
cc young

답변:


67

ES6를 사용하면 간단하게 다음을 수행 할 수 있습니다.

const spanList = [...document.querySelectorAll("span")];

이것은 나에게Type 'NodeListOf<Element>' must have a '[Symbol.iterator]()' method that returns an iterator.ts(2488)
콜백

안녕하세요 @callback, 이것은 TypeScript 관련 오류처럼 보입니다. tsconfig 파일의 lib 배열에 "es6"을 추가하지 않고 es6 컴파일을 대상으로 선택했을 수 있습니다. 감사합니다
Freezystem

1
안녕하세요 @Freezystem, 당신이 맞습니다! es2015를 타겟팅하고 있습니다. 감사!
콜백

@callback ES6와 ES2015는 동일합니다
DarkNeuron

65

ES6에서는 Array.from(myNodeList). 그런 다음 좋아하는 배열 방법을 사용하십시오.

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 1
Array.from(myNodeList).forEach(function(el) {
  console.log(el);
});

ES6 shim 을 사용하여 이전 브라우저 에서도이 작업을 수행하십시오.


트랜스 파일러 (예 : Babel)를 사용하는 경우 두 가지 대안이 더 있습니다.

var myNodeList = document.querySelectorAll('.my-selector');

// ALT 2
for (var el of myNodeList) {
  el.classList.add('active'); // or some other action
}

// ALT 3
[...myNodeList].forEach((el) => {
  console.log(el);
});

nodeList가 반복자를 제공한다는 es6에서도 사실이 아닙니까?
cc young

4
@ccyoung하지만 이터레이터는 비 호환 ES6 브라우저에서 작동하지 않습니다. Symbol 객체를 shim 할 수 없기 때문에 shimm 할 수 Array.from(myNodeList)있기 때문에 사용하는 것이 좋습니다 .
Roc 2011 년

그래서 나는 Array.from (el.childNodes)가 배열의 일부로 첫 번째 노드를 반환하지 않는이 문제가 있습니다.
zinoadidi

49

프로토 타입 의 slice메소드를 사용하여 배열로 변환 할 수 있습니다 Array.

var elList = document.querySelectorAll('.viewcount');
elList = Array.prototype.slice.call(elList, 0);

당신이 필요로하는 모든 경우 또한 forEach, 당신은 호출 할 수있는 것을 으로부터 Array먼저 배열에 강요하지 않고, 프로토 타입 :

var elList = document.querySelectorAll('.viewcount');
Array.prototype.forEach.call(elList, function(el) {
    console.log(el);
});

ES6에서는 새 Array.from함수를 사용하여 배열로 변환 할 수 있습니다 .

Array.from(elList).forEach(function(el) {
    console.log(el);
});

이것은 현재 블리딩 엣지 브라우저에서만 가능하지만 폴리 필 서비스사용하는 경우 전반적 으로이 기능에 액세스 할 수 있습니다.


ES6 트랜스 파일러를 사용 하는 경우 for..of대신 루프를 사용할 수도 있습니다 .

for (var element of document.querySelectorAll('.some .elements')) {
  // use element here
}

감사. 더 간결한 강제가 있었으면하는 새로운 자바 스크립트 생각 / 희망 아래.
cc young

6
@cc young-내가 Array.prototype.forEach대신 사용하는 이유 [].forEach는 후자가 완전히 불필요한 새로운 Array 객체를 생성하기 때문입니다.
Joseph Silber 2011 년

@JosephSilber 아 감사합니다-생성 된 새 배열이 비어 []있습니까? 내 생각은 가비지가 수집되고 메모리 영향은 무시할 만하다고 생각합니다. 누구나 이것에 대해 언급 할 수 있습니까?
Daniel Sokolowski 2015-04-25

@Daniel 이것은 사실이지만 배열을 만들고 파괴하는 계산이 여전히 있습니다.
Brett

21

왜 변환합니까? - call요소 수집에서 직접 배열의 기능;)

[].forEach.call( $('a'), function( v, i) {
    // do something
});

물론 $querySelectorAll 의 별칭 이라고 가정 합니다.


편집 : ES6는 더 짧은 구문을 허용합니다 [...$('a')]( 2014 년 5 월 현재 Firefox에서만 작동 ).


가정 $입니다 querySelectorAll.
c69

3
귀하의 대답은 jQuery 사용을 의미합니다. 그럴 경우 .each().
Matt Ball

1
롤, 왜? 같은 별칭을 만드는 것을 금지하는 것은 없습니다 function $ ( s ) { return document.querySelectorAll(s); }.
c69

5
jQuery를 사용한다면 더 $('a').each(function(i, v) {...});
간결한

2
offtopic : EcmaScript 5는 이미 1 년 동안의 표준이며, 현재 세대의 모든 브라우저는 새로운 Arrays 메서드를 지원하며 특히 NodeList 일명 Element 컬렉션에서 이러한 메서드를 사용하는 것에 대한 질문이있었습니다.
c69

9

그래야합니까 forEach? for루프를 사용하여 목록을 반복 할 수 있습니다 .

for (var i = 0; i < elementList.length; i++) {
    doSomethingWith(elementlist.item(i));
}

1
불필요한 배열 변환을 추가하지 않는 간단한 솔루션을 사용하는 경우 +1. 참고로, 대신 elementList.item(i), 당신은 사용할 수 있습니다 elementList[i].
jfriend00

4
개인적으로 찾아 forEach()더 나은 프로그래밍 스타일과 덜 장황를 - YMMV
젊은 CC

@cc young : 사실 동의합니다. 이와 같은 경우를 제외하고는 내가 좋아하는 패턴을 사용할 수 있도록 변환을 실행해야합니다. 그것은 투박하게 만들고 다음과 같이 보입니다. "당신이 가진 모든 것이 망치이면 모든 것이 못처럼 보이기 시작합니다."
nfechner 2011 년

그리고 여기에 nuttier 방법입니다 :) for (var oElement, i = 0; oElement = aMenuItemsElements; i++ { console.log(oElement); }
다니엘 Sokolowski

여기서 문제 for (var i…)는 for 루프가 자체 범위를 만들지 않기 때문에 다른 루프를 중첩 할 수 없다는 것입니다 (지금 C / C ++에서와 같이). 그리고 i혼란 스러워요.
Jens

9

2020 업데이트 : nodeList.forEach ()는 이제 공식 표준 이며 모든 현재 브라우저에서 지원됩니다.

이전 브라우저는 아래 폴리 필을 사용할 수 있습니다.

예를 들어 forEach ()를 사용하여 자바 스크립트의 목록에서 작동하려면 NodeList를 배열로 변환해야합니다.

그건 사실이 아니야. .forEach()현재 브라우저에서 작동합니다. 누락 된 경우 Array 에서 NodeList로 .forEach ()를 추가 할 수 있으며 제대로 작동합니다.

if ( ! NodeList.prototype.forEach ) {
  NodeList.prototype.forEach = Array.prototype.forEach;
}

이제 다음을 실행할 수 있습니다.

myNodeList.forEach(function(node){...})

배열과 마찬가지로 NodeList를 반복합니다.

이것은 모든 곳에서 .call ()보다 훨씬 짧고 깨끗한 코드를 생성합니다.


1
이 대답은 정확히 내가 필요로하는 것이었고이 3 줄은 많은 시간을 절약했습니다. 다른 모든 답변은 코드를 변경해야했을 것이며 그 이유를 이해할 수 없습니다.
Scribblemacher

downvotes는 아마도 원숭이 패치 내장 프로토 타입이 나쁜 관행으로 간주 되었기 때문일 것입니다
DuBistKomisch

@DuBistKomisch 이것은 표준 NodeList.foreach ()가 존재하지 않는 경우에만 적용되는 polyfill입니다.
mikemaccana

1
아 내 나쁜, 그들이 실제로 forEach구체적으로 추가 filter
했다는 것을 몰랐습니다.

@DuBistKomisch에 대해 동일한 기술을 사용할 수 filter있지만 NodeList.prototype.dbkFilter다른 구현을 사용하는 향후 표준에 대해 걱정이되는 경우 비공식적 인 이름 또는 유사한 이름을 지정할 수 있습니다 .
mikemaccana

2

ES6는 멋진 방법을 허용 var nodeArray = Array.from(nodeList)하지만 제가 가장 좋아하는 것은 새로운 스프레드 연산자입니다.

var nodeArray = Array(...nodeList);

완벽한 솔루션! 이 솔루션은 Typescript에도 적용됩니다.
Nirus

ES5 이하로 트랜스 파일하지 않는 한 TypeScript에서만 작동한다고 덧붙이고 싶습니다.
Rudey

2

ES6에서 저와 함께 일했습니다.

그런 노드 목록이 있다고 가정하겠습니다.

<ul>
  <li data-time="5:17">Flexbox video</li>
  <li data-time="8:22">Flexbox video</li>
  <li data-time="3:24">Redux video</li>
  <li data-time="5:17">Flexbox video</li>
  <li data-time="7:17">Flexbox video</li>
  <li data-time="4:17">Flexbox video</li>
  <li data-time="2:17">Redux video</li>
  <li data-time="7:17">Flexbox video</li>
  <li data-time="9:54">Flexbox video</li>
  <li data-time="5:53">Flexbox video</li>
  <li data-time="7:32">Flexbox video</li>
  <li data-time="2:47">Redux video</li>
  <li data-time="9:17">Flexbox video</li>

</ul>


const items = Array.from(document.querySelectorAll('[data-time]'));

console.log(items);

2

읽기가 가장 쉽다고 생각하기 때문에 다음을 사용합니다.

const elements = document.getElementsByClassName('element');
[...elements].forEach((element) => {
   // code
});


1

글쎄, 이것은 나에게도 효과적입니다.

const elements = Object.values( document.querySelector(your selector here) )

Object.values()Array주어진 객체의 값을 반환 합니다. NodeListJS의 모든 것이 그렇듯이 객체입니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values

하지만 IE와는 호환되지 않으므로 Array.prototype.*array_method*.call(yourNodeList)최선의 선택이라고 생각 합니다. 이것으로 당신은 당신의 모든 배열 메소드를 호출 할 수 있습니다.NodeList


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.