페이지 요소(Element) 탐색

Posted in 모바일/Javascript // Posted at 2010.10.12 13:49

기본적으로 웹 페이지는 요소(Element)라고 부르는 개체들의 모음이다
div, table, img 등 각각의 태그는 특정 요소를 정의하기 위한 마크업 규칙이며 이 요소들이 모여 웹 페이지를 구성한다. 이들 요소는 기본적으로는 페이지에 정적으로 표시되지만 스타일 처리와 동적 구현을 위해 자바스크립트와 같은 언어로 핸들링 할 수 있다

이러한 핸들링을 위한 가장 첫 단계가 바로 페이지에 존재하는 요소를 찾아내는 일이다. 이를 '페이지 요소 탐색'이라 한다. 이 글에서는 페이지 요소 탐색을 위한 과거와 현재의 기술적 이슈를 다루고자 한다

document.all
아마 필자와 같은 구식(?)  웹 개발자들은 제일 먼저 document.all 을 떠 올렸을 것이다
요소에 부여된 id를 기반으로 탐색하는데 매우 낡은 방법이다.

아래와 같이 페이지의 div 요소에 "myDiv" 라는 id를 부여했다고 가정한다
<div id="myDiv">ABCD</div>

그리고 다음과 같이 이 요소를 탐색한다
var element = document.all["myDiv"]; alert(element1.nodeName);

그러나 요즘 시대에 이런 낡은 문법을 사용한다면 욕 듣기 딱 쫗다 ㅎㅎ
왜냐하면 비표준 스크립트라는 이유에서이다

document.all 은 과거 마이크로소프트의 인터넷 익스플로러에 채택된 DOM 스크립트이다.당시 넷스케이프에서는 document.layers 와 대응되는 문법이었다. 이러한 비표준 스크립트는 크로스브라우저 환경에 큰 걸림돌이기 때문에 사용을 권장하지 않는다

모든 브라우저에서 사용가능한 document.all ??
document.all 은 MS 가 IE를 위한 비표준 탐색 스크립트지만 현재 존재하는 대부분의 최신 브라우저에서 이를 지원하고 있다.  즉 IE는 물론 크롬, 사파리, 파이어폭스, 오페라에서 잘 동작한다.그럼 표준인가?? ...
그렇지 않다. 표준이라기보다는 워낙 유명한(?) 문법이라 IE호환성을 위해 각 브라우저에서 이를 지원하게 된 것일 뿐이다. 이와 관련한 다음의 글을 참고하기 바란다
=> Mozilla, document.all 부분 지원 시작!   ,  document.all 문제 해결법


document.getElementById
아마 모든 웹 개발자가 알고 있는 문법일 것이다
비표준 탐색 스크립트를 평정하고 W3C 에서 표준으로 정한 탐색 스크립트가 바로 document.getElementById 이다. 앞서 document.all을 다음과 같이 대체할 수 있다. 그리고 표준이기 때문에 브라우저 호환성이 보장된다
var element = document.getElementById("myDiv");

이제 document.all 은 잊어 버리고 document.getElementId 를 사용하자. 이미 오래전에 잊었겠지만...


document.getElementsByTagName
getElementById 와 쌍을 이루는 유명한 문법일 것이다.
getElementsByTagName는 getElementById와 마찬가지로 표준 스크립트이며 딱 두가지 차이점이 존재한다.

1) 하나 이상의 요소 즉 요소의 배열을 반환한다
getElementsByTagName 이 반환하는 것은 요소배열이다.
비록 반환되는 요소가 단 1개라도 배열 접근 형식(ex element[0]) 을 취해야 한다.

2) 요소에 부여된 ID가 아닌 태그에 기반한다
getElementById 가 요소에 부여된 ID를 기반으로 탐색을 수행한다면, getElementsByTagName는 요소의 태그명에 기반한다. 즉 div, table, img 와 같은 요소태그를 대상으로 탐색을 수행한다

이런 특징은 일종의 유연성을 제공해 준다. getElementById와 같이 ID를 기반으로 한다는 것은 일종의 규칙이다. 즉 미리 정의된 ID가 있어야 한다는 규칙이 성립해야 한다. 만일 웹 문서 파서(parse)와 같은 범용적인 외부 제작툴을 개발한다면 이런 규칙을 적용할 수 없기 때문에 공통적인 태그를 기반으로 한다는 것이 유연성이 있다는 예기이다

페이지에 다음과 같이 두개이 div가 정의되어 있다면,
<div>First Div</div>  <div>Second Div</div>

다음과 같이 전체 div요소를 탐색할 수 있다
var element = document.getElementsByTagName("div");    

for(var i = 0; i < element.length; i++){
   alert(element[i].nodeName);  
}


document.getElementsByClassName
웹킷(webkit) 기반 브라우저에서 적용한 탐색 스크립트이다.
getElementByID의 경우 ID가 부여된 단 하나의 요소만을 탐색할 뿐이며 getElementsByTagName의 경우 동일 태그의 모든 요소를 반환한다. 만일 임의의 이름이 부여된 특정 그룹을 탐색하고자 할 경우 이 두가지만으로는 한번에 만족시킬 수 없다. getElementsByClassName 은 그 이름에서도 알 수 있듯이 className 이 부여된 요소(그룹)을 반환한다.

페이지에 다음과 같이 동일한 class가 부여된 div 요소가 정의되어 있다면,
<div class="myDivClass">First Div</div>
<div class="myDivClass">Second Div</div>

다음과 같이 class 명으로 div 요소 그룹을 탐색할 수 있다

var element1 = document.getElementsByClassName("myDivClass");    
    
for(var i = 0; i < element1.length; i++){
   alert(element1[i].nodeName);  
}

참고로 아래 그래프는 getElementsByClassName 과 이와 같은 기능을 xPath, 혹은 커스텀 스크립트로 개발할 대의 스크립트 속도차이를 보여준다. 브라우저 차원에서 제공하는 네이티브 getElementByClassName의 수행 속도가 현저히 빠르다는 것을 보여주고 있다


getElementsByClassName 은 현재 IE8(이하) 를 제외하고는 대부분의 브라우저에서 지원된다
그러나 이 함수는 HTML5 스펙에 포함되었으며 IE 버전 9 부터는 같이 지원될 예정이다


document.querySelectorAll
CSS Selector 규칙을 그대로 이용할 수 있는 방법이 생겼다
W3C 에서는 보다 유연한 탐색을 지원하기 위해 CSS 규칙을 기반으로 하는 Selectors API 를 표준화 시켰다
querySelectorAll 함수를 통해 CSS 탐색 규칙을 맘껏(?) 적용할 수 있다

페이지에 다음과 같이 div 안에 p 요소가 정의되었다고 가정할 때,
<div id="myDiv">
   <p>First paragraph.</p>
   <p>Second paragraph.</p>
</div>

다음과 같이 CSS 규칙을 이용하여 요소를 쉽게 탐색할 수 있다
var element = document.querySelectorAll("#myDiv p");

for(var i = 0; i < element.length; i++ ) {  
    element[i].style.backgroundColor = "red";
}

또한 querySelector 을 통해 특정 요소를 다음과 같이 탐색할 수 있다
var element = document.querySelector("#myDiv > p:first-child")
alert(element.nodeName);

중요한 것은 CSS 탐색 규칙 즉 CSS Selector 을 이용하여 보다 강력한 탐색이 가능하다는 점이다

참고로 querySelectAll 은 IE8 을 포함한 크롬, 사파리, 오페라, 파이어폭스에서 모두 지원하지만
다른 브라우저가 CSS 3 Selector 까지 지원하는 반면 IE8은 CSS 2.1 Selector 까지만 지원된다

다음의 링크를 통해 CSS Selector 에 대한 자세한 정보를 확인하자
- CSS 2.1 Selector
- CSS 3 Selector
- CSS Selector 상세 브라우저 지원 현황
- CSS 3 selectors explained


Selector 라이브러리를 통한 탐색
근래 웹을 개발하는 거의 모든 사람이 추천하는 jQuery, Prototype 과 같은 자바스크립트 라이브러리에서는 훌륭한 탐색 기능을 제공해 준다. 이들 라이브러리는 브라우저 호환성을 제공하고 빠른 수행 속도가 보장되기 때문에 그 사용이 권장되고 있는 추세이다. 다만 스크립트 해석이 한번 더 랩핑된 형태라 아무래도 브라우저 차원에서 제공되는 네이티브(Native) 보다는 수행속도가 조금 떨어지는 것은 사실이다
그러나 비용 대비 효과면에서는 충분히 수용할 만한 아니 그 이상의 성능을 보여주고 있기 때문에 권장된다
다음 그림은 각각의 탐색 API를 활용할 경우 수행 속도의 차이를 보여준다

출서: FireFox3.5의 DOM selectors API

다음 글은 탐색과 관련한 유용한 정보를 제공해 주니 읽어보기 바란다
참고: FireFox3.5의 DOM selectors API

submit