2009-09-10 3 views
0

오픈 소스 프레임 워크 (jQuery 등)를 사용하지 않고 JavaScript에서 어떤 컨트롤의 속성을 검색하는 가장 효율적인 방법은 무엇입니까? (이전/새 브라우저)JavaScript의 검색 속성

다음과 같은 패턴입니다. 어떤 더 좋은 방법이나 더 나은 getElementByAttribute() 방법이 있습니까? 감사!

예컨대

<input type="button" id="b1" value="Continue" a1="something" /> 
<input type="text" id="t1" a1="something1" /> 

<script> 
var attrToFind = "something;something1"; 

var elems = document.all ? document.all : document.getElementByTagName("*"); 
//assume elems work always 
for(var i = 0 ; i < elems.length; i++) 
{ 
    var att = elems[i].getAttribute("a1"); 
    if (typeof att == "string") 
    { 
    if (att.indexOf(attrToFind) > -1) 
    ... //search which attr you find, create array, save value, etc. 
    } 
} 
</script> 
+1

당신은 이미 올바른 생각을 가지고 있다고 생각합니다. 테스트가 약합니다. 값이 "무언가"라면 "무언가"와 일치 할 것입니다. 그러나 그것은 쉽게 해결할 수 있습니다. 더 큰 문제는 매번 전체 DOM을 통과해야하기 때문에 큰 문서의 경우 매우 느릴뿐입니다. 이것이 jQuery/Sizzle과 같은 선택기 엔진이보다 구체적인 선택자를 권장하는 이유입니다. 'input [a1 = something]'은 입력 요소를 테스트하기 만하면됩니다. – Shog9

답변

1

있습니다. 브라우저가 document.querySelectorAll (CSS 표현식) 또는 document.evaluate (xpath 표현식)과 같은 요소를 수집하는 다른 수단을 지원한다고 가정하면 이러한 "특수화 된"방법이 일반적으로 더 효율적입니다. (getElement[s]By* 기능에 의해 반환)을 HTMLCollectionHTMLCollection 항상 (이 라이브 입니다)에서 문서를 일치해야하기 때문에 배열 접근에 비해 느린입니다 액세스

document.querySelectorAll('*[foo="bar"]'); 
document.evaluate("//*[@foo='bar']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); 
+0

@kangax : 흥미 롭습니다 ... querySelectorAll에 대해 전혀 몰랐습니다. 새 브라우저와 오래된 브라우저에서는 작동하지 않으므로 실제로 사용할 수 없다고 생각합니다. @ Shog9 : 그래, 내 길을 느리게하는 것은 내 두려움뿐입니다. 그렇기 때문에 JS 전문가에게 물어보기 위해 여기에 질문을 게시했습니다. –

+0

그래, 가능한 경우 이러한 방법 중 하나를 사용하는 래퍼 함수를 ​​작성해야합니다. 그렇지 않으면 전체 문서를 걷는 것에 넘어집니다. 이것은 많은 프레임 워크가하는 것입니다 (일부는 문자열을 올바르게 이스케이프 처리하지 못합니다 ...) – bobince

1

.

이 이유 때문에 HTMLCollection에서 배열을 만들고 그 위에 반복하는 것이 가장 좋습니다.

var attrToFind = "something;something1", 
    elems = document.all ? document.all : document.getElementByTagName('*'), 
    i, attr; 

// Works in Firefox; not sure about other browsers and engines. 
elems = Array.prototype.slice.call(elems); 

i = elems.length; 

while(i --> 0) { 
    attr = elems[i].getAttribute('a1'); 

    // Are you sure you want indexOf? 
    // att === attrToFind may be faster, as it requires one less comparison. 
    if(typeof att !== 'string' || att.indexOf(attrToFind) < 0) { 
     continue; 
    } 

    // Do stuff. 
} 
+0

@stranger : 코드 스 니펫이 낙관적 인 것처럼 보입니다. 나 해보자. 고마워! –

+0

그래, IE6은 Array.prototype.slice.call (elems)을 좋아하지 않았고 안타깝게도 (우리 모두에게) 내가 지원해 줬다. –

+0

@ Rac123, 당신은 아마 반복하고 IE6에 대한 새로운 배열로 복사 할 수 있습니다. 순진한 해결책을 잡는 것보다 현재 콜렉션 - 배열 행 주위에 try 블록을 추가하십시오. – strager

0

이 어쩌면이 솔루션은 당신이 무엇을 필요가있다 :

function $$$$(obj) { 

var attrToFind = obj; 
var elements = document.getElementsByTagName('*'); 
var attrResults = []; 

var x = 0; 
while (x < elements.length) { 
    var attr = elements[x].getAttribute('a1'); 

    if (attr !== null) { 
     if (attr.indexOf(attrToFind) > -1) { 
      attrResults.push(elements[x]); 
     } 
    } 
    x++ 
} 
return attrResults; 

}

실행 기능 :

$$$$('something'); 

은 조금 더 빠른 속도에 최적화되어 있습니다

결과가있는 배열입니다. 클래스 '무언가'가있는 모든 요소. 아마도 누군가가 내 코드를 리팩토링 할 수 있으므로 하나 이상의 매개 변수로도 작업하고 있습니다.

도와 드리겠습니다.