IE에서 innerHTML 사용시 주의해야할 점

일단, 발행하기 전에 정리부터 하자..
예제는 나중에 정리하고.. 생각나는대로 써보면,..
대충 정리해보면 아래와 같다.

1. DOM 노드 캐싱
DOM을 캐싱할때는,.. 캐싱하려는 노드를 cloneNode(true)로 떠서 캐시하자..
그렇치 않으면, IE에서는 innerHTML로 해당 노드를 날렸을때,. 캐시한 노드까지 날라간다.
반면, IE외의 다른 브라우저에서는 innerHTML로 해당 노드를 날렸을때..
해당 노드만 날라가고, 캐시한 노드는 그대로 있다.
[하나 더 주의] – cloneNode를 할 경우, 바인딩된 이벤트는 복사되지 않는다.!

2. 메모리 누수
모든 브라우저가 innerHTML로 엘리먼트를 교체하면, 엘리먼트가 걸려있는 이벤트 핸들러들이
날아가 버린다. 보다 정확한 의미는 참조를 잃어버린다!!
때문에 참조를 잃어버린 이벤트 핸들러들은 영영 해제할 길이 없어 메모리 누수가 생긴다.

따라서, 엘리먼트 교체를 해야할 경우엔, 이벤트 핸들러를 먼저 제거해주거나..
앞에서 얘기한 노드를 캐싱하거나..
아니면, HTML로 날릴만한 엘리먼트엔 이벤트 핸들러를 걸지말고, 그 상위 노드에 걸어서
버블링 처리를 해라~!!

3. HTML 렌더링
HTML을 innerHTML로 재할당을 할경우, 브라우저는 재할당한 부분만 랜더링을 다시하게 된다.
이때, 구식브라우저(꼬진브라우저, 느린브라우저)인 IE6에서는 랜더링 할때, 생각보다 속도가 느리다.
그래서 아래와 같이 사용하게 되면,..

node.innerHTML = “<div>….중간생략 복잡한 디비전 태그 교체…</div>”
doSomethingHere();

doSomethingHere() 함수 안에서 새로 랜더링 되는 엘리먼트의 width나 height 등을 가지고 뭔 짓꺼리를 하게 되면,
IE6에서는 htmlfile 에러는 내뱉는다.

이유는 앞서 설명했듯이 랜더링 속도가 느려서 발생하는 문제로…
로드 된후, 실행시 까지 약간의 딜레이를 주거나,
인터벌울 돌려서 렌더링이 됐는지 체크를 한다.

난 걍 랜더링시 문제가 될경우에 한에서만 이렇게 쓴다.

el.innerHTML = sTpl;
var oInstance = this;
setTimeout(function(){
          oInstance._initialize();
}, 100);

4. htmlfile 에러
그밖에 IE6혹은 IE7에서 htmlfile 에러가 발생하는 경우가 있는데 아래와 같은 경우가 있다.

  1. 붙이려는 노드가 읽기 전용 속성의 태그이고, 거기에 ID 값을 부여해서 innerHTML 할 경우
    ** IE에서 COL COLGROUP FRAMESET HTML STYLE TABLE TBODY TFOOT THEAD TITLE TR 개체등은 ID 필드가 읽기전용 속성이고 그 외의 개체에서는 모두 읽기/쓰기가 된다.
  2. 기본 HTML 구조 규칙을 깨는 경우,
    예를 들면, LI 엘리먼트 하위에 다시 LI 노드를 자식으로 넣는 경우가 있겠다.
    이 경우는 실제로 겪었던 부분으로, li 자식 노드로 li를 넣는 바보같은 짓을 범했다. 이런 경우가 흔하지 않는 경우인데, 안타까운건 FF 에서는 li 하위에 li 를 짚어 넣어도 아무런 에러를 발생시키지 않는 다는 것이다. 


5. FireBug를 믿지마라!

보통 FireFox의 플러그인 인 firebug 를 이용해서 디버깅을 하게되는데, FF 는 너무나 관대(?)해서,
IE에서 뱉는 에러를 몇몇가지를 그냥 쌩까고 혹은 아~ 이건 개발자 실수니까,..스마트(?) 하게 알아서 정정해준다.
즉, FF만 믿고 개발했다가는 IE 호환성에 적신호를 받게 될것이다.
그렇다고, firebug 가 구리다는건 아니고, 간간히 중간중간 때때로, 생각날때, IE 브라우저로 테스트를 해보는 습관을 갖는게 좋겠다.

추천하는 바는 그냥  IE6 브라우저를 버리고 갔으면 한다. (그냥 개인적인 바램~ OTL… ㅜㅜ )
하지만 현실은 시궁창… ㅎㅎ