<td>
를 클릭하면 이벤트가 최상위 조상부터 시작해서 아래로 전파되고(캡처링 단계), 이벤트가 타깃 요소에 도착해 실행된 후(타깃 단계), 다시 위로 전파됨(버블링 단계)Note
- 거의 모든 이벤트는 버블링됨
- 버블링되지 않는 이벤트
- 포커스 이벤트 :
focus
,blur
- 리소스 이벤트 :
load
,unload
,abort
,error
- 마우스 이벤트 :
mouseeter
,mouseleave
event.stopPropagation()
event.stopImmediatePropagation()
Note
- 꼭 필요한 경우를 제외하고는 버블링을 막지 않기
event.target
을 사용하여 접근 가능함event.target
event.currentTarget(=this)
addEventListener
의 capture
옵션을 true
로 설정해야함capture
옵션이 false
(default)이면, 핸들러는 버블링 단계에서 동작함capture
옵션이 true
이면, 핸들러는 캡처링 단계에서 동작함element.addEventListener(..., {capture: true})
// or
element.addEventListener(..., true)
event.target
을 사용해 이벤트가 발생한 요소가 어디인지 알아냄<div id="menu">
<button data-action="save">저장하기</button>
<button data-action="load">불러오기</button>
<button data-action="search">검색하기</button>
</div>
<script>
class Menu {
constructor(element) {
this._element = element;
element.onclick = this.onClick.bind(this);
}
save() {
alert('저장하기');
}
load() {
alert('불러오기');
}
search() {
alert('검색하기');
}
onClick(event) {
let action = event.target.dataset.action;
if (action) {
this[action]();
}
}
}
</script>
장점 | 원인 | 결과 |
---|---|---|
장점 1 | 여러 개의 요소가 아닌 공통 조상 요소에만 핸들러 할당하면 됨 | 초기화가 단순해짐, 메모리 절약됨 |
장점 2 | 요소를 추가/제거할 때 해당 요소 핸들러를 추가/제거하지 않아도 됨 | 코드의 길이가 짧아짐 |
장점 3 | innerHTML 이나 유사한 기능을 하는 스크립트로 요소 덩어리를 추가/제거 가능함 | DOM 수정이 쉬워짐 |
단점 | 원인 | 결과 |
---|---|---|
단점 1 | 이벤트 위임을 사용하려면 이벤트가 반드시 버블링되어야 함 | 버블링되지 않는 이벤트들이 있음 |
단점 2 | 컨테이너 수준에 할당된 핸들러가 모든 하위 요소에서 발생하는 이벤트에 응답해야 함 | CPU 작업 부하가 늘어날 수 있음 (무시할 만한 수준임) |