일반 DOM과 innerHTML 방법에 대한 비교 분석

황제낙엽 2008.11.03 13:21 조회 수 : 94 추천:96

sitelink1  
sitelink2  
sitelink3  
sitelink4 http://1 
extra_vars4 ko 
extra_vars5 http://blog.naver.com/dihkang/30014391194 
extra_vars6 sitelink1 
DOM과 innerHTML 방법에 대한 비교 분석
   Date: 2006-12-17, 03:31 AM
자바스크립트로 HTML 문서의 엘리먼트를 동적으로 생성하거나 업데이트를 하려면 DOM의 Element 함수를 이용하거나 간단히 innerHTML 프러퍼티를 이용하면 된다. 여러 사람들이 전자를 DOM 방법, 후자를 innerHTML 방법이라 일컫고 있다.
예를 들어, 아래의 DIV 엘리먼트에 자식 요소로 'Hello Word' 라는 버튼을 생성하는 스크립트를 생각해 보자.
1 <div id="mycontentdiv"></div> 
view plain | print | copy to clipboard | ?
먼저, DOM 방법으로 스크립트를 작성한다면 아래와 같다.
1 var mydiv = document.getElementById("mycontentdiv");  
2 var btn = document.createElement("input");  
3 btn.type = "button";  
4 btn.value = "Hello Word";  
5 mydiv.appendChild(btn);  
view plain | print | copy to clipboard | ?
<소스 1>
그리고, innerHTML 방법은 아래와 같다.
1 var mydiv = document.getElementById("mycontentdiv");  
2 mydiv = "<input type='button' value='Hello Word'>";  
view plain | print | copy to clipboard | ?
<소스 2>
얼핏 보기에 효율과 성능, 그리고 기타 여러 면에서 후자의 방법이 바람직하다고 판단할 수도 있겠지만 모든 상황에서 반드시 그렇지만은 않다.
앞서 본바처럼 innerHTML 방법은 딸랑 두줄로 끝날 것을 어느 미친 개발자가 복잡하고 힘들게 DOM 방법으로 구현할까 단순히 생각하기 쉽겠지만, DOM 방법이 유용할 상황도 있고 반드시 DOM 방법을 써야만 할 때도 있다.
먼저, 반드시 DOM 방법을 써야할 상황은 innerHTML을 지원하지 않는 엘리먼트의 자식 엘리먼트를 다루아야 할 때다. 브라우저마다 innerHTML을 프러퍼티를 Read-only로만 지원되거나 innerHTML 프러퍼티 자체가 없는 엘리먼트가 있고 각기 다른데, IE의 경우 그 태그 목록은 다음과 같다.
COL, COLGROUP, FRAMESET, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR
IE뿐만 아니라 그 외 파이어폭스와 오페라 등의 브라우저도 TABLE 관련 엘리먼트에서 innerHTML을 사용할 수 없다. 사실, 이점은 innerHTML을 사용하는데 있어 크게 문제 되지는 않는다. 그러나 HTML 문서의 엘리먼트를 빈번하고 세심하게 업데이트해야 하고 기존의 이벤트 리스너를 계속 유지해야 하는 상황이라면 DOM 방법이 효율적이다. 예를 들어, 아래의 DIV 엘리먼트의 첫번째 자식 엘리먼트인 'Hello Word' 버튼 엘리먼트에 onclick 이벤트에 대한 핸들러가 할당되어 있을때 자식 엘리먼트로 '<input type="text" value="innerHTML vs. DOM">'를 추가해야 한다고 가정해보자.
1 <div id="mycontentdiv">  
2 <input type="button" value="Hello Word">  
3 </div> 
4  
5 <script type="text/javascript">  
6  
7 var div = document.getElementById("mycontentdiv");  
8 var input = div.getElementsByTagName("input")[0];  
9  
10 input.addEventListener("click", iamclicked, true);  
11  
12 function iamclicked() {  
13        alertt("I am clicked.");  
14 }  
15  
16 </script> 
17  
view plain | print | copy to clipboard | ?
<소스 3>
먼저 DOM 방법으로 구현한다면 아래의 소스4를 소스3에 추가하면 된다.
1 var mydiv = document.getElementById("mycontentdiv");  
2 var btn = document.createElement("input");  
3 btn.type = "text";  
4 btn.value = "innerHTML vs. DOM";  
5 mydiv.appendChild(btn);  
view plain | print | copy to clipboard | ?
<소스 4>
그 다음으로 innerHTML 방법으로 구현한 소스는 아래와 같다.
1 var mydiv = document.getElementById("mycontentdiv");  
2 mydiv.innerHTML += "<input type='text' value='innerHTML vs. DOM'>";  
view plain | print | copy to clipboard | ?
<소스 5>
여기서 퀴즈 하나. 과연 위의 소스4와 소스5의 결과가 같을까? 답은 같지 않다이다. 소스5의 innerHTML 방법은 'Hello World' 버튼의 onclick 이벤트 핸들러를 잃어버리게 되는 결과를 가져 온다. 원래의 소스3에서는 'Hello World' 버튼을 클릭하면 iamclicked 함수가 호출되어 'I am clicked.' 라는 알림창을 띄워 주는데 소스5를 추가하면 'Hello World' 버튼을 클릭해도 'I am clicked.' 알림창이 안 뜨게 된다. 이렇듯 innerHTML을 사용하지 못하는 경우 DOM 방법을 사용해야 하는데 getElementById, createElement, appendChild 등 작성해야할 코드가 많고 이런 작업들은 개발자에게는 매우 귀찮은 일이다. 그러나 이런 힘들고 귀찮은 DOM 스크립팅을 누워서 떡먹기보다 쉽게 할 수 있는 방법들을 사용하면 노가다의 지옥에서 구원 받을 수 있다.