Santos의 개발블로그

element.addEventListener에 대해서 본문

Language & Framework & Library/JavaScript

element.addEventListener에 대해서

Santos 2023. 11. 12. 15:31

 

대부분의 회사에서 사용 되고 있는 React, Vue와 같은 프레임워크, 라이브러리들의 trade off는 항상 존재한다고 믿어왔다. 요즘 그러한 생각들이 더욱 드는 이유는 사내에서 에디터를 만들면서  관련된 기능의 내부 동작을 정확하게 알지 모른채 사용하는 메서드들이 생기고 있기 때문이다. 빠른 기능 구현을 해야하는 핑계로 인해 기술에 대한 합리화를 제 자신이 하고 있지 않은가에 대해 다시 생각해보면서, 이 글을 기록한다. 

 


addEventListener

자바스크립트를 이용해서 어떤 이벤트를 등록할 때 내부적으로 다음과 같다. 

var event_listener_list = [];
var sayHi = function() {
  console.log('hi');
};
window.addEventListener('click', sayHi);
--------- 위의 동작은 아래처럼 변환된다 ---------
event_listener_list.push({
  type: 'click',
  callback: sayHi,
  capture: false, 
  passive: false,
  once: false,
  signal: false
});

 

이벤트 핸들러를 등록하면 자바스크립트는 하나의 큐에 리스너들이 등록된 차례대로 저장이 된다. 요소들은 하나의 객체로 저장된다. 

 

각 이벤트 정보들은 이벤트 타입, 이벤트 콜백 함수, 캡처링 여부, 패시브 여부(preventDefault 여부), once 여부(한번 실행 여부), signal (abort 메서드를 호출시 제거)의 대한 정보를 담는다.

만약 이벤트 타입, 콜백 함수와 여러 기타 옵션의 동일한 값이 이미 등록되어 있다면, 자바스크립트는 새로운 이벤트를 등록하지 않는다. 

 


var log = function(x) {
  console.log(x);
};
window.addEventListener('click', () => log(1));
window.addEventListener('keydown', () => log(2));
window.addEventListener('dbclick', () => log(3));

 

하나의 예시를 들어보자. 위와 같이 각 다른 정보를 가진 이벤트 핸들러를 등록하게 되면 다음과 같이 적재된다. 

[event_listener_list]
index  type    callback      ...
  0    click   (anonymous)
  1    keydown (anonymous)
  2    dbclick (anonymous)

 

서로가 다른 이벤트 정보를 가지기에 모두 이벤트 리스너 큐에 등록된다. 

그렇다면 같은 이벤트 타입의 핸들러를 여러개 등록한다면 어떤식으로 찾을 수 있을까? 

굉장히 다른 타입을 가진 이벤트들이 많더라도, 0번 index 순서대로 차례대로 검사하여 알맞은 이벤트를 실행 시켜준다. 


그렇다면 아래와 같은 케이스는 어떨까? 

window.addEventListener('click', () => log(1));
window.addEventListener('click', () => log(2));
window.addEventListener('click', () => log(3));

 

모두 같은 타입을 가진 이벤트 핸들러고 log 함수를 호출하는 것 까지는 같지만, 콜백 함수는 익명 함수이기때문에  자바스크립트는 같은 이벤트로 판단할 수 없어 3개의 핸들러를 모두 등록시킨다. 그렇기에 아래와 같은 방법으로 해결 하는 것이 좋다. 

var i = 1;
function log() {
  console.log(i++);
}
window.addEventListener('click', log);
window.addEventListener('click', log);
window.addEventListener('click', log);

 

익명함수가 아닌 기명함수로 등록하여 같은 메모리 주소를 가진 콜백 함수를 이벤트 핸들러로 넘겨준다. 이때 자바스크립트는 모두 같은 핸들러로 판단한다. 그리하여 처음 한 번만 이벤트를 등록하고 나머지 이벤트 등록은 무시하게 된다. 


< 참고자료 >

[사이트] #addEventListener

 

EventTarget: addEventListener() method - Web APIs | MDN

The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.

developer.mozilla.org

element.addEventListener에 대해서 end

반응형

 

 
 
Comments