[javascript] Javascript에서 DOM 노드 목록을 배열로 변환하는 방법은 무엇입니까?

HTML 노드 목록을 받아들이는 Javascript 함수가 있지만 Javascript 배열을 기대하고 (일부 Array 메서드를 실행합니다) Document.getElementsByTagNameDOM 노드 목록을 반환하는 출력을 제공하고 싶습니다 .

처음에는 다음과 같은 간단한 것을 사용하려고 생각했습니다.

Array.prototype.slice.call(list,0)

그리고 이것은 모든 브라우저에서 잘 작동합니다. 물론 “JScript object expected”라는 오류를 반환하는 Internet Explorer를 제외하고, Document.getElement*메서드에 의해 반환 된 DOM 노드 목록 은 함수 호출의 대상이 될만큼 JScript 개체가 아닙니다.

주의 사항 : Internet Explorer 특정 코드를 작성하는 데는 신경 쓰지 않지만 제 3 자 웹 사이트에 삽입 할 위젯을 작성하고 있기 때문에 JQuery와 같은 Javascript 라이브러리를 사용할 수 없으며 다음과 같은 외부 라이브러리를로드 할 수 없습니다. 클라이언트에 충돌이 발생합니다.

내 마지막 도랑 노력은 DOM 노드 목록을 반복하고 직접 배열을 만드는 것입니다.하지만 더 좋은 방법이 있습니까?



답변

NodeList는 호스트 객체입니다 . 호스트 객체 에서 Array.prototype.slice메서드를 사용하는 것은 작동이 보장되지 않습니다. ECMAScript 사양은 다음과 같이 말합니다.

슬라이스 기능이 호스트 객체에 성공적으로 적용될 수 있는지 여부는 구현에 따라 다릅니다.

간단한 함수를 만들어 NodeList각 기존 요소를 반복 하고 배열에 추가 하는 것이 좋습니다 .

function toArray(obj) {
  var array = [];
  // iterate backwards ensuring that length is an UInt32
  for (var i = obj.length >>> 0; i--;) {
    array[i] = obj[i];
  }
  return array;
}

최신 정보:

다른 답변에서 알 수 있듯이 이제 최신 환경에서 스프레드 구문 또는 Array.from방법을 사용할 수 있습니다 .

const array = [ ...nodeList ] // or Array.from(nodeList)

그러나 그것에 대해 생각하면 NodeList를 Array로 변환하는 가장 일반적인 사용 사례는 그것을 반복하는 것입니다. 이제 NodeList.prototype객체는 forEach기본적으로 메소드를 가지고 있으므로 최신 환경에 있다면 직접 사용할 수 있습니다. pollyfill.


답변

es6 에서는 다음과 같이 사용할 수 있습니다.

  • 스프레드 연산자

     var elements = [... nodelist]
  • 사용 Array.from

     var elements = Array.from(nodelist)

https://developer.mozilla.org/en-US/docs/Web/API/NodeList 에서 더 많은 참조


답변

스프레드 사용 (ES2015) 과 같이 쉽습니다.[...document.querySelectorAll('p')]

(선택 사항 : Babel 을 사용 하여 위의 ES6 코드를 ES5 구문으로 변환)


브라우저의 콘솔에서 시도해보고 마법을 확인하십시오.

for( links of [...document.links] )
  console.log(links);


답변

이 간단한 트릭 사용

<Your array> = [].map.call(<Your dom array>, function(el) {
    return el;
})


답변

실제로 적절한 shim은 아니지만 DOM 요소 작업을 요구하는 사양이 없기 때문에 다음과 slice()같은 방식으로 사용할 수 있도록 하나를 만들었습니다 . https://gist.github.com/brettz9/6093105

업데이트 : 내가 DOM4 사양의 편집기로 이것을 제기했을 때 (그들이 호스트 객체에 자신의 제한을 추가 할 수 있는지 묻습니다 (사양은 구현자가 배열 메서드와 함께 사용할 때 이러한 객체를 올바르게 변환해야 함) 그는 “호스트 객체는 ES6 / IDL에 따라 다소 쓸모가 없습니다.”라고 답했습니다. 나는 당을 참조 http://www.w3.org/TR/WebIDL/#es-array 사양은 그러나 “플랫폼 배열 객체”를 정의하기 위해 IDL을 사용할 수 http://www.w3.org/TR/domcore/ 아무튼 새 IDL을 사용하지 않는 것 같습니다 HTMLCollection( Element.attributesDOMString 및 DOMTimeStamp에 대해 WebIDL을 사용하고 있음을 명시 적으로 만 명시하지만 그렇게하는 것처럼 보이지만). 나는 봅니다[ArrayClass](Array.prototype에서 상 속됨)이 사용됩니다 NodeList( NamedNodeMap이제 여전히 사용하는 유일한 항목을 위해 더 이상 사용되지 않습니다 Element.attributes). 어쨌든 표준이 될 것 같습니다. ES6 Array.from는 또한 지정해야하는 것보다 더 편리 할 수도 있고 더 Array.prototype.slice의미 론적으로 명확 할 수도 있습니다 [].slice()(그리고 더 짧은 형식 Array.slice()( “배열 제네릭”)이 내가 아는 한 표준 동작이되지 않음).


답변

오늘날 2018 년에는 ECMAScript 2015 (6th Edition) 또는 ES6를 사용할 수 있지만 모든 브라우저가이를 이해할 수있는 것은 아닙니다 (예 : IE가 모든 것을 이해하지 못함). 원하는 경우 다음과 같이 ES6를 사용할 수 있습니다 :
var array = [... NodeList];( 확산 연산자로 ) 또는 var array = Array.from(NodeList);.

다른 경우 (ES6를 사용할 수없는 경우) 가장 짧은 방법을 사용하여 a NodeListArray .

var array = [].slice.call(NodeList, 0);.

예를 들면 :

var nodeList = document.querySelectorAll('input');
//we use "{}.toString.call(Object).slice(8, -1)" to find the class name of object
console.log({}.toString.call(nodeList).slice(8, -1)); //NodeList

var array = [].slice.call(nodeList, 0);
console.log({}.toString.call(array).slice(8, -1)); //Array

var result = array.filter(function(item){return item.value.length > 5});

for(var i in result)
  console.log(result[i].value); //credit, confidence
<input type="text" value="trust"><br><br>
<input type="text" value="credit"><br><br>
<input type="text" value="confidence">

그러나 DOM노드 목록을 쉽게 반복하려는 경우 a NodeListArray. 다음을 NodeList사용하여 항목을 반복 할 수 있습니다 .

var nodeList = document.querySelectorAll('input');
// Calling nodeList.item(i) isn't necessary in JavaScript
for(var i = 0; i < nodeList.length; i++)
    console.log(nodeList[i].value); //trust, credit, confidence
<input type="text" value="trust"><br><br>
<input type="text" value="credit"><br><br>
<input type="text" value="confidence">

목록의 항목 을 사용 for...in하거나 for each...in열거 하려고하지 마십시오 . 목록의 길이와 항목 속성도 열거되므로NodeList 스크립트에서 요소 개체 만 처리해야한다고 가정하면 오류가 발생하기 때문입니다. 또한 for..in특정 순서로 숙소 방문을 보장하지 않습니다. for...of루프는 NodeList 객체를 올바르게 반복합니다.

참조 :


답변

var arr = new Array();
var x= ... get your nodes;

for (i=0;i<x.length;i++)
{
  if (x.item(i).nodeType==1)
  {
    arr.push(x.item(i));
  }
}

이것은 작동해야합니다. 크로스 브라우저를 사용하면 모든 “요소”노드를 얻을 수 있습니다.