jQuery event에 특정 namespace를 만들어 제어하기

May 15, 2019

jQuery를 이용한 공통 모듈을 만드는 경우, 이벤트를 바인딩 하고, 어느 시점에는 해제해야 하는 경우가 있습니다. 이러한 경우, browser에 정의된 공통의 이벤트를 통해 바인딩 하게 되면, .off 시점에 공통의 정의된 이벤트가 모두 해제되는 사이드이펙트가 발생할 수 있습니다.

예를 들면, window 객체에 scroll event를 바인딩하고, 이후에 해당 이벤트를 해지한다고 가정해보겠습니다.

    $(window).on('scroll', () => {
    	console.log('event-1');
    });
    
    $(window).on('scroll', () => {
    	console.log('event-2');
    }

특정 시점에, 첫번째에 바인딩했던 event-1을 해지하려고 하면, scroll이라는 이벤트를 가지고 있는 모든 이벤트가 해제되는 현상이 발생할 것입니다.

jQuery에서는 이러한 현상에 대한 분기점을 가지기 위해서, event 객체 내에 namespace를 가지고 있습니다. 해당 이벤트를 바인딩 하고, chrome dev tool 콘솔에 다음과 같이 입력해서 이벤트를 확인할 수 있습니다.

    $._data($(window)[0], 'events');

해당 코드는, jQuery내에 target elemet에 등록된 모든 이벤트 목록을 조회하는 함수입니다. 해당 코드를 입력하면, 다음과 같은 결과를 확인할 수 있습니다.

event namespace가 없는 경우

scroll이라는 이벤트는 Array 형태로 관리되며, 현재 3, 4번째 index에 관련된 이벤트가 바인딩 되어 있는 것을 확인할 수 있습니다. (관련된 내용은 개발된 내용에 따라, index가 달라질 수 있습니다.) 확인해보면, 각 index내에 namespace라는 property가 존재하며, 이를 통해서 이벤트 name을 추가적으로 분기하고 있습니다. 만약 .off function을 이용하여 scroll 이벤트를 해제하면, namespace가 따로 존재하지 않기 때문에 scroll로 정의된 모든 이벤트가 해제됩니다.

namespace를 사용하는 방법은 쉽습니다. 이벤트 이름에 {event이름}.{namespace}를 통해서 정의할 수 있습니다. 위의 코드를 다음과 같이 수정해 보겠습니다.

    $(window).on('scroll.one', () => {
    	console.log('event-1');
    });
    
    $(window).on('scroll.two', () => {
    	console.log('event-2');
    });

이벤트를 확인하는 코드를 크롬 개발자도구에서 다시 실행해보시면, 다음과 같이 표시되는 것을 확인하실 수 있습니다.

event namespace가 있는 경우

위의 스크린샷과 같이, 이제 namespace에 one 이라는 이벤트와 two라는 이벤트가 바인딩 된 것을 확인할 수 있습니다. 이를 통해서, 삭제하고 싶은 이벤트만 삭제하기 위해서는 다음과 같이 삭제할 수 있습니다.

    $(window).off('scroll.one');

위의 코드는 scroll 이벤트중, one이라는 namespace를 가지고 있는 이벤트만 해제하는 코드로써, 기타 다른 scroll 이벤트에 영향을 주지 않고, scroll.one이라는 이벤트만 해제할 수 있게 됩니다.

...