2012-12-19 1 views
18

뭔가 document.getElementsBy*querySelectorAll이 반환 한 가상 배열에서 forEach를 사용할 수있는 방법은 무엇입니까? 것 자바 스크립트 일반 좋은

This'd jQuery를에 덜 의존, 단순히 청소기 코드로 이어질, document.querySelectorAll에 의해 반환 된 항목에 forEach, map, filter 등을 사용할 수 있도록 . 바로 지금, 이것은 우리가 추한 방식으로 할 수있는 방법입니다 :

[].forEach.call(document.querySelectorAll(sel), function(el) { 
}); 

이것은 ... 자세한 정보입니다.

forEach 등의 요소를 즉시 사용할 수있는 방법은 무엇입니까?

NodeList.prototype.forEach = Array.prototype.forEach; 

이 작동 : 당신은 크롬에서 테스트하는 경우

+1

왜 모든 사용자가'Array.prototype.forEach'를 사용하는 대신 배열 ('[]')을 할당합니까? –

답변

14

본래의 방법은이 작업을 수행하는 것입니다. 웹킷에서. Firefox에서는 그렇지 않습니다. FF는 HTMLCollection ...

내가 찾은 가장 크로스 브라우저 방식을 반환하므로 :

NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach; 

그것은 IE8에서 작동하고 호스트 오브젝트에 속성을 추가 할 때 그들은 숨이 있기 때문에, 비록 낮은되지 않습니다 프로토 타입.

전체 목록 :

NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach; 
NodeList.prototype.map = HTMLCollection.prototype.map = Array.prototype.map; 
NodeList.prototype.filter = HTMLCollection.prototype.filter = Array.prototype.filter; 
NodeList.prototype.reduce = HTMLCollection.prototype.reduce = Array.prototype.reduce; 
NodeList.prototype.reduceRight = HTMLCollection.prototype.reduceRight = Array.prototype.reduceRight; 
NodeList.prototype.every = HTMLCollection.prototype.every = Array.prototype.every; 
NodeList.prototype.some = HTMLCollection.prototype.some = Array.prototype.some; 

또는은, 우리의 친애하는 BERGI을 기쁘게하기 위해 (그리고 또한 청소기이기 때문에) :

['forEach', 'map', 'filter', 'reduce', 'reduceRight', 'every', 'some'].forEach(
    function(p) { 
    NodeList.prototype[p] = HTMLCollection.prototype[p] = Array.prototype[p]; 
}); 

perfectionkills에 대한 링크를 고려하면, 그것은이 대부분 무관합니다. 문제는 확장 될 때 DOM이 브라우저에서 거의 동일하게 작동하지 않는다는 것입니다. 이 수정은 IE < = 8을 제외한 모든 브라우저에서 정상입니다.

+4

http://perfectionkills.com/whats-wrong-with-extending-thedom/에 대한 링크가 없습니다. 또한, "전체 목록"에 대한 루프를 사용하십시오 – Bergi

+0

@Bergi 편집 됨 : –

+0

나는 dom을 확장하고 싶지 않습니다. – andlrc

6
function forEach(a, fn) { 
    return [].forEach.call(a, fn); 
}; 

forEach(document.querySelectorAll(sel), function(el) { 
}); 

그리고 많은 사람들이 더 :

function map(a, fn) { 
    return [].map.call(a, fn); 
}; 
function filter(a, fn) { 
    return [].filter.call(a, fn); 
}; 
function reduce(a, fn) { 
    return [].reduce.call(a, fn); 
}; 
function reduceRight(a, fn) { 
    return [].reduceRight.call(a, fn); 
}; 
function every(a, fn) { 
    return [].every.call(a, fn); 
}; 
function some(a, fn) { 
    return [].some.call(a, fn); 
}; 

은 아마 당신은 어떤 상황에서

[].slice.call(a) 

가 필요합니다.

function forEach(a, fn) { 
    return [].forEach.call([].slice.call(a), fn); 
} 
+0

어, 그래, 그걸 잊어 버렸다. 차라리 'bind'메서드를 사용하고 싶습니다. (어떻게 해야할지 기억이 안납니다.) 그러나 나는 아직도 내 대답에 나와있는 방법을 선호한다. 그것은 더 "dommy"를 느낀다. –

+0

@FlorianMargaine 내 생각 엔 누군가가 처녀 창녀라고 생각하니 ?? – andlrc

+1

Nope. 솔직히 질문/대답은 모자 사냥이었다. 나는 정직하게 대답하는 방법을 선호한다. 이전의 코멘트에서 말했듯이, 나는 당신의 방식에 대해 이미 알고있었습니다 - 나는 단지 그것을 특별히 좋아하지 않습니다. 게다가, 내가 왜 이미 rep 한거야? –

2

당신은 프로토 타입을 변경 좋아하고 모든 배열 함수는 그냥 배열에 컬렉션을 변환하는 것이 더 쉬울 수 있고, 일을 바로하지 않으려면 :

Array.from(document.querySelectorAll('a')) 

모든 배열 기능을 사용할 수 있습니다

관련 문제