블로그 내 검색

2011. 9. 17.

Javascript 이벤트 바인딩 별 차이

DOM Element에 이벤트를 바인딩하는 방법은 몇가지 방법이 있다

인라인(In-line) 방식
함수 레퍼런스 방식
addEventListener 방식
attachEvent 방식

이 넷은 일견 다 비슷해 보인다.
하지만 함부로 위 방법을 혼용해서 썼다간 원치 않는 이벤트 동작이 일어날 수도 있다.
특히 함수 내에 thisarguments 등의 늦은 바인딩 변수를 썼을 경우에는 문제가 심각해진다.

예제를 통해 이들의 차이를 알아보자
일단 함수를 하나 선언하는데 이 함수의 내용은 자신의 활성 객체(Activation Object) 아이디를 알려주는 기능을 한다.
그리고 객체 다섯개를 선언하고 그것마다 다른 방식의 이벤트 바인딩을 한 뒤 호출해본다.

 
// 테스트를 위해 윈도우의 프로퍼티에 아이디를 추가해둔다
window.id = "window";

// 자신의 컨텍스트 아이디를 보여줄 바인딩 함수
function clickObj() {
    alert(this.id);
}

window.onload = function() {
    
    // 이벤트를 지정할 참조 엘리먼트를 얻는다.
    var ele = document.getElementById("reference");

    // 함수 레퍼런스 방식. 함수의 참조를 그대로 이벤트에 복사
    ele.onclick = clickObj;
    
    // 이벤트 익명 함수 안에서 함수 실행
    ele = document.getElementById("referenceInner");
    ele.onclick = function(){
        clickObj();
    };
    
    // IE 전용의 이벤트 추가 메서드 이용
    if(ele.attachEvent) {
        ele = document.getElementById("attachEvent");
        ele.attachEvent("onclick", clickObj);
    }
    
    // 표준 이벤트 리스너 등록
    else if(ele.addEventListener) {
        ele = document.getElementById("addEventListener");
        ele.addEventListener("click", clickObj, false);
    }
};


예제의 결과를 보면

inline : window
attachEvent : IE전용, window
addEventListener : 표준 브라우저. addEventListener
reference : reference
referenceInner : window 

다음의 결과를 얻을 수 있다.

인라인 방식의 this는 글로벌
attachEvent의 this는 글로벌
addEventListener의 this는 
Activation Object
reference방식의 this는 
Activation Object 
reference지만 익명 함수 안의 this는 글로벌

인라인 방식은 함수의 활성객체가 글로벌(window) 객체이다.

하지만 함수 레퍼런스 방식과 addEventListener 방식은 바인딩 된 객체임을 알 수 있다.
레퍼런스 방식에서도, 레퍼런스 함수에서 다른 함수를 호출할 경우 그 함수의  활성 객체는 글로벌(window) 객체가 된다.

재미있는 점은 표준을 싫어하는(?) IE의 경우이다.
IE에서 지원하는 이벤트 바인딩 메서드는 활성 객체가 글로벌 객체로 지정되어 버린다.
캡처링도 지원 안하는 메서드가 무슨 깡으로 이런 오류까지 내는지 알 길이 없다(?)

이들의 차이를 잘 알지 못한채 함부로 스크립트를 만들다 보면 나중에 잡기 힘든 오류와 정신적 탭탠스를 추며 퇴근시간이 늦어지는 불상사가 있을지도 모르겠다.

댓글 없음:

댓글 쓰기