브라우저는 특정 사건을 감지하면 특정한 타입의 이벤트를 발생시킨다. 만약 이벤트가 발생할 때 어떤 일을 하고싶다면, 계속 지켜보고 있을 수는 없으니 브라우저에게 어떤 일을 할 것인지 함수 호출을 위임한다.
이때, 그 함수를 이벤트 핸들러라고 하며 등록 방법에는 1)이벤트 핸들러 어트리뷰트 방식, 2)이벤트 핸들러 프로퍼티 방식, 3)addEventListener 메서드 방식이 있다.
<input value="클릭해!" onclick="alert('클릭!')" type="button">
<input value="클릭해!" type="button">
<script>
elem.onclick = function() {
alert('클릭!');
};
</script>
(위 두 방법은 복수의 핸들러를 할당할 수 없으며, 타깃단계와 버블링단계의 이벤트만 캐치할 수 있다.)
element.addEventListener(event, handler, [options]);
(addEventListener방식은 복수의 이벤트 리스너를 등록할 수 있으며, 버블링 단계는 물론 캡처링 단계에서도 활용할 수 있다.)
DOM요소 노드에서 발생한 이벤트는 DOM트리를 통해 전파된다.
HTML에서 자식 요소는 부모 요소 안에 겹쳐진 상태로 표시되는데, 이벤트가 발생한 경우 컴퓨터가 부모 요소에서 발생한 것인지 자식 요소인지 구분할 수 없다. 그래서 이벤트가 발생하면 그 요소의 조상요소까지 전체에서 해당 이벤트의 이벤트 처리기나 이벤트 리스너가 있는지 확인하는 과정이 필요한 것이다.
이벤트 전파는 캡처링 단계, 타깃 단계, 버블링 단계의 3단계로 구분할 수 있다.
클릭해!
위 버튼을 클릭하면 클릭 이벤트가 발생하여 이벤트에 관한 정보를 담은 이벤트 객체가 생성된다. 클릭된 button요소는 이벤트 타깃이 된다.
캡처링 단계: 클릭 이벤트 객체는 Window에서 이벤트 타깃(button) 방향으로 전파된다.
이 단계에 반응하도록 등록된 이벤트 리스너는 이벤트가 발생한 요소에 등록된 이벤트 리스너보다 먼저 실행된다. 캡처링 단계는 잘 활용하지 않는다.
타깃 단계: 이벤트 객체가 이벤트를 발생시킨 이벤트 타깃에 도달한다.
이벤트 타깃의 이벤트 처리기/이벤트 리스너가 실행된다.
버블링단계: 다시 이벤트 객체가 이벤트 타깃에서 window방향으로 전파된다.
이 단계에서 반응하도록 등록된 이벤트 리스너가 이벤트 타깃에 등록된 이벤트 리스너 다음에 실행된다.
(대부분의 이벤트는 캡처링과 버블링을 통해 전파되지만, 아래 이벤트들은 그 요소에만 필요한 이벤트이므로 버블링을 통해 전파되지 않는다.)
포커스 이벤트 focus/blur
리소스 이벤트 load/unload/abor/error
마우스 이벤트 mouseenter/mouseleave
캡처링과 버블링을 이용하여 이벤트 위임 패턴을 구현할 수 있다.
이벤트 위임은 하나의 상위 DOM 요소에 이벤트 핸들러를 등록해 하위 DOM 요소에 일일이 이벤트 핸들러 등록하는 것을 대신하는 방법을 말한다.
이를 이용하면 동적으로 하위 DOM 요소를 추가하더라도 따로 이벤트 핸들러를 등록해줄 필요가 없어지며, 메모리가 절약된다.