계층적 구조에 포함되어 있는 HTML 요소에 이벤트가 발생할 경우 연쇄적 반응이 일어난다.
즉, 이벤트가 전파(Event Propagation)되는데 **전파 방향에 따라 버블링(Event Bubbling)과 캡처링(Event Capturing)**으로 구분할 수 있다.
- 버블링 : 자식 요소에서 발생한 이벤트가 부모 요소로 전파
- 캡쳐링 : 자식 요소에서 발생한 이벤트가 부모 요소부터 시작하여 이벤트를 발생시킨 자식 요소까지 도달
→ 즉 하위 요소에서 부모요소로 가는 것을 버블링, 반대로 부모요소에서 하위요소로 내려오는 것을 캡처링이라고 한다.
버블링과 캡처링
: 이벤트가 제일 깊은 곳에 있는 요소에서 시작해 부모 요소를 거슬러 올라가며 발생하는 모양이 마치 물속 거품(bubble)과 닮았기에 그러한 이름이 붙었다.
→ 거의 모든 이벤트와 버블링이 되지만, focus와 같은 이벤트는 버블링 되지 않는다.
즉, 이벤트가 발생했을 때 캡처링과 버블링은 순차적으로 발생한다. 캡처링은 IE8 이하에서 지원되지 않는다.
캡처링과 버블링은 이벤트 등록할 때 정의가능하다. addEventListener메소드를 보면
target.addEventListener(type, listener[, useCapture]);
→ 첫번째 인자는 type이다.
- click – 마우스버튼을 클릭하고 버튼에서 손가락을 떼면 발생한다.
- mouseover – 마우스를 HTML요소 위에 올리면 발생한다.
- mouseout – 마우스가 HTML요소 밖으로 벗어날 때 발생한다.
- mousedown – 클릭을 하기 위해 마우스버튼을 누르고 아직 떼기 전인 그 순간, HTML요소를 드래그할 때 사용할 수 있다.
- mouseup – 마우스버튼을 떼는 그 순간, 드래그한 HTML요소를 어딘가에 놓을 때 사용할 수 있다.
- mousemove – 마우스가 움직일때마다 발생한다. 마우스커서의 현재 위치를 계속 기록하는 것에 사용할 수 있다.
- focus – HTML요소에 포커스가 갔을때 발생한다.
- blur – HTML요소가 포커스에서 벗어났을때 발생한다.
- keypress – 키를 누르는 순간에 발생하고 키를 누르고 있는 동안 계속해서 발생한다.
- keydown – 키를 누를 때 발생한다.
- keyup – 키를 눌렀다가 떼는 순간에 발생한다.
등으로 많이 쓰인다.
→ 두번째 인자는 콜백 함수로 이벤트가 발생되면 실행된다.
→ 세번째 인자인 useCapture는 캡처링 여부를 의미한다.
- capture - boolean으로 default값이 false이기에 안 써줘도 인자가 디폴트로 인식한다. 캡처링을 하고자 하면, useCapture에 true로 입력하면 된다.
- once - boolean으로 true로 하면 이벤트가 딱 한번 발생한다.
- passive - boolean으로 true으로 하면 콜백 함수 내부에 preventDefault()로 함수를 실행했더라도 실행되지 않는다.
→ 한 요소에 여러가지 이벤트를 등록할 수 있다. 여러가지 요소에 여러가지 이벤트도 등록할 수 있다.
target
부모 요소의 핸들러는 이벤트가 정확히 어디서 발생했는지 등에 대한 자세한 정보를 얻을 수 있다.
이벤트가 발생한 가장 안쪽의 요소는 타깃(target) 요소라고 불리고, event.target을 사용해 접근할 수 있다.
form.onclick 핸들러 내의 this와 event.target은 다음과 같다.
- this(event.currentTarget) – 만약 <form> 요소에 있는 핸들러가 동작했다면, 이는 <form> 요소를 가리킵니다.
- event.target – 폼 안쪽에 실제 클릭한 요소를 가리킵니다.
→ this = event.target이 되게 된다.
중단
그런데 핸들러에게 이벤트를 완전히 처리하고 난 후 버블링을 중단하도록 명령할 수도 있습니다.
이벤트 객체의 메서드인 event.stopPropagation()를 사용하면 됩니다. 캡처링의 경우 클릭한 element의 최상위 이벤트만 동작하고, 하위 이벤트는 발생하지 않는다. 반대로 버블링의 경우 최하위 요소의 이벤트만 발생하고, 상위 이벤트는 동작치 않는다. 그리고 event.stopImmediatePropagation()을 사용하면 동일한 대상의 이벤트 흐름뿐만 아니라 다른 유사 이벤트도 중지시킬 수 있다.
→ 버블링을 멈춰야 하는 상황이 아니라면 버블링을 막으면 안된다.
removeEventListener
: 등록된 이벤트리스너를 지운다.
이벤트를 등록후에
event.removeEventListener('이벤트종류','콜백함수');
써서 이벤트를 지울 수 있다.
표준 DOM 이벤트에서 정의한 이벤트 흐름엔 3가지 단계가 있습니다.
- 캡처링 단계 – 이벤트가 하위 요소로 전파되는 단계
- 타깃 단계 – 이벤트가 실제 타깃 요소에 전달되는 단계
- 버블링 단계 – 이벤트가 상위 요소로 전파되는 단계
아래의 사이트는 참고한 사이트입니다.
https://chlolisher.tistory.com/10
https://chlolisher.tistory.com/22
https://ko.javascript.info/bubbling-and-capturing