Programing

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

lottogame 2020. 9. 20. 10:31
반응형

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 전용 코드를 작성하는 데는 신경 쓰지 않지만, 타사 웹 사이트에 포함 할 위젯을 작성하고 있기 때문에 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 에서 더 많은 참조


spread (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;
})

While it is not really a proper shim, since there is no spec requiring working with DOM elements, I've made one to allow you to use slice() in this manner: https://gist.github.com/brettz9/6093105

UPDATE: When I raised this with the editor of the DOM4 spec (asking whether they might add their own restrictions to host objects (so that the spec would require implementers to properly convert these objects when used with array methods) beyond the ECMAScript spec which had allowed for implementation-independence), he replied that "Host objects are more or less obsolete per ES6 / IDL." I see per http://www.w3.org/TR/WebIDL/#es-array that specs can use this IDL to define "platform array objects" but http://www.w3.org/TR/domcore/ doesn't seem to be using the new IDL for HTMLCollection (though it looks like it might be doing so for Element.attributes though it only explicitly states it is using WebIDL for DOMString and DOMTimeStamp). I do see [ArrayClass] (which inherits from Array.prototype) is used for NodeList (and NamedNodeMap is now deprecated in favor of the only item that would still be using it, Element.attributes). In any case, it looks like it is to become standard. The ES6 Array.from might also be more convenient for such conversions than having to specify Array.prototype.slice and more semantically clear than [].slice() (and the shorter form, Array.slice() (an "array generic"), has, as far as I know, not become standard behavior).


Today, in 2018, we could use the ECMAScript 2015 (6th Edition) or ES6, but not all browsers can understand it (for ex. IE does not understand all of it). If you want you could use ES6 as follows: var array = [... NodeList]; (as spread operator) or var array = Array.from(NodeList);.

In other case (if you can not use ES6) you can use the shortest way to convert a NodeList to an Array:

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

For example:

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">

But if you want to iterate over the DOM node list easy only, then you do not need to convert a NodeList to an Array. It's possible to loop over the items in a NodeList using:

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">

Don't be tempted to use for...in or for each...in to enumerate the items in the list, since that will also enumerate the length and item properties of the NodeList and cause errors if your script assumes it only has to deal with element objects. Also, for..in is not guaranteed to visit the properties in any particular order. for...of loops will loop over NodeList objects correctly.

See too:


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));
  }
}

This should work, cross browser and get you all the "element" nodes.

참고URL : https://stackoverflow.com/questions/2735067/how-to-convert-a-dom-node-list-to-an-array-in-javascript

반응형