TIL29 l Event Listener

Noma·2021년 1월 29일
0
post-custom-banner

1. Event

이벤트는 마우스를 클릭하거나 키보드를 누르는 등 사용자 액션에 의해 발생할 수도 있고, 혹은 비동기적 작업의 진행을 나타내기 위해 API가 생성할 수도 있습니다.

이벤트의 종류는 다양하며 일부는 Event 인터페이스의 파생 인터페이스를 사용합니다. 또한 이벤트 자체는 모든 이벤트 공통 속성과 메소드를 가집니다.

Event 객체, 속성, 메소드는 다음 포스팅에서 자세히 다루니 어떤 것들이 있는지만 확인하세요.

1.1 Property

  • Event.target (읽기 전용)
    : 이벤트가 처음에 발생했던 대상의 참조입니다.

  • Event.currentTarget (읽기 전용)
    : 이벤트를 위해 현재 등록된 대상의 참조로, 이벤트가 현재 전달되기로한 객체입니다. 재 타게팅을 통해 변경될수도 있습니다.

  • 이 외에 더 많은 프로퍼티가 존재합니다. (MDN 참조)

1.2 Method

  • Event.composedPath( )
    : 이벤트의 경로, 즉 수신기를 발동할 모든 객체를 반환합니다. 섀도우 루트의 ShadowRoot.modeclosed인 경우 섀도우 트리의 노드는 포함하지 않습니다.

  • Event.preventDefault( )
    : 취소 가능한 경우 이벤트를 취소합니다.

  • Event.stopImmediatePropagation( )
    : 이 특정 이벤트에 대해서 다른 모든 수신기의 호출을 방지합니다. 같은 요소에 부착된 수신기는 물론 캡처 단계 등 이후에 순회활 요소에 부착된 수신기도 이 이벤트를 받지 않습니다.

  • Event.stopPropagation( )
    : 이벤트의 DOM 내 추가 확산을 방지합니다.

2. Event Listener(handler)

EventTarget 객체로부터 발생한 이벤트를 처리하기 위한 오브젝트를 말합니다. 많은 DOM 요소들은 이벤트 리스너로 이벤트를 받고("수신"), 받은 이벤트를 "처리"하는 코드를 실행할 수 있습니다.

이벤트 처리기는 대개 EventTarget.addEventListener()를 사용해 다양한 요소(<button>, <div>, <span>, 등등)에 "부착"합니다. 그리고 제대로 추가한 경우, 반대로 removeEventListener()로 제거할 수도 있습니다.

2.1 이벤트 리스너 등록

이벤트 등록 방법은 현재까지는 3가지가 있습니다. 각각의 방식마다 장단점, 유의사항이 있으니 확인 하고 넘어가도록 합시다.

2.1.1 Inline 방식

인라인 방식은 html 자체에 이벤트 리스너를 연결하는 방법입니다.
예제 1

<button onclick="testHandler()">Test</button>
<script>
  function testHandler() {
  alert('Hello world');
  }
</script>

예제 2

<button onclick="alert('Hello world');">Test</button>

하지만, HTML과 자바스크립트는 분리가 원칙이므로(유지보수를 쉽게 하기 위해) 권장되는 방법이 아닙니다.

또한 위와 같이 하면 이벤트가 발생할 때 eval과 비슷한 자바스크립트 내부 메소드가 실행되는 데(new Function) 이러한 eval 기능은 자바스크립트에서 피해야하는 것 중 하나입니다.

2.2.2 Property 방식

자바스크립트 프로퍼티를 사용해 이벤트 리스너를 등록하는 방법입니다.

예제

window.onload = function () {
  alert('I\'m loaded');
};

window가 load될 때 function 부분이 실행됩니다(load됐다는 것은 브라우저가 알려줌). 이는 예시 중 하나일 뿐 window 말고도, 여러 태그에 각각 이벤트를 설정할 수 있습니다.

위와 같은 구조로 모든 DOM들이 EventTarget을 상속하기 때문에 어떠한 태그도 이벤트 리스너를 등록할 수 있습니다.

그러나 이 방식에는 하나의 요소에 다수의 처리기를 가질 수 없다는 단점이 존재합니다.

예제

window.onload = function () {
  alert('Hello world1');
};
window.onload= function () {
  alert('Hello world2');
}
// Hello world2

위 코드를 보면, 하나의 요소에 하나의 이벤트 핸들러만 등록이 가능하기때문에 마지막으로 등록된 이벤트 핸들러만 작동하는 것을 알 수 있습니다.

2.2.3 addEventListener( )

EventTarget의 addEventListener()는 지정한 이벤트가 대상에 전달될 때마다 호출할 함수를 설정합니다. 일반적인 대상은 Element, Document, Window지만, XMLHttpRequest와 같이 이벤트를 지원하는 모든 객체를 대상으로 지정할 수 있습니다.

이 방법은 Property 방식과 달리 하나의 요소에 다수의 처리기를 가질 수 있습니다. 완전히 동일한 이벤트에 대해서도, 예컨대 광고 모듈과 통계 모듈이 각각 비디오 시청을 추적하는 등 여러 처리기를 따로 등록할 수 있습니다.

addEventListener()는 다음과 같은 특징을 가지고 있습니다.

  • "on"이 붙지 않은 이벤트 타입을 사용한다.
  • 캡처링과 버블링을 지원한다. (해당 내용은 다음 포스팅에서 다룹니다.)
  • IE 9 이상에서 동작 한다.
    (IE 8이하에는 attachEvent() 방식을 사용해야 한다.)

예제

const testBtn2 = document.querySelector('#testBtn2');

testBtn2.addEventListener('click', testFunc); 
testBtn2.addEventListener('click', ()=> alert('Hello world2'));

function testFunc(){
  alert('Hello world1'); 
}

testBtn2를 클릭하면 Hello world1 과 Hello world2 가 모두 대화 상자로 띄워지는 것을 확인 할 수 있습니다.

2.2 이벤트 리스너 제거

2.2.3 removeEventListener()

EventTarget.removeEventListener() 메서드는 이전에EventTarget.addEventListener()로 EventTarget 에 등록했던 이벤트 리스너를 제거합니다.

이 이벤트 리스너는 이벤트 종류와 이벤트 리스너 함수 자체의 조합으로 식별되어 제거되며, 등록시 제공했던 다양한 옵션과 일치하는 이벤트 리스너만 제거할 수 있습니다.

예제

testBtn2.removeEventListener('click', testFunc);
// 이벤트 타입이 click이며, 연결된 함수 이름이 testFunc인 이벤트 리스너 제거

❗ 참고 자료
https://www.zerocho.com/category/JavaScript/post/57432d2aa48729787807c3fc
https://goddaehee.tistory.com/269
https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener

profile
오히려 좋아
post-custom-banner

0개의 댓글