<html>
<body>
<!-- 분홍색 -->
<div class="pink" onClick="alert(this.className)">
<!-- 보라색 -->
<div class="purple" onClick="alert(this.className)">
<!-- 파란색 -->
<div class="blue" onClick="alert(this.className)">
blue
</div>
</div>
</div>
</body>
</html>
거의 모든 이벤트는 버블링이 된다!!
event.stopPropagation()
을 활용하면 된다!!
<html>
<body>
<!-- 분홍색 -->
<div class="pink" onClick="alert(this.className)">
<!-- 보라색 -->
<div class="purple" onClick="alert(this.className); event.stopPropagation()">
<!-- 파란색 -->
<div class="blue" onClick="alert(this.className)">
blue
</div>
</div>
</div>
</body>
</html>
이렇게 작성하면 파랑색, 보라색 alert만 뜨고 분홍색 alert는 뜨지 않는다!!
하지만 하나의 요소에서 다양한 이벤트 핸들러가 존재할 경우, event.stopPropagation()을 활용하면 이벤트들 중 하나만 버블링을 멈추고 나머지 이벤트들은 동작하게 된다.
하나의 요소에 할당된 모든 이벤트 동작을 막기 위해서는 event.stopImmediatePropagation()
을 활용해야 한다!!
버블링은 유용한 기능이기 때문에 버블링을 꼭 멈춰야 하는 상황이 아니라면 버블링을 막지 않는것이 좋다!!
캡처링을 활용하려면 addEventListener의 capture 옵션을 true로 설정해야 한다!
elem.addEventListener(..., {capture: true}) // {capture: true} 대신 간단하게 true만 작성해도 됨! elem.addEventListener(..., true)
<html> <body> <!-- 분홍색 --> <div class="pink"> <!-- 보라색 --> <div class="purple"> <!-- 파란색 --> <div class="blue"> blue </div> </div> </div> </body> <script> for(let elem of document.querySelectorAll('*')) { elem.addEventListener("click", e => alert(`[캡쳐링] tag: ${elem.tagName}, class: ${elem.className}`), true); elem.addEventListener("click", e => alert(`[버블링] tag: ${elem.tagName}, class: ${elem.className}`)); } </script> </html>
이렇게 작성하게 되면, 가장 상단 요소에서부터 이벤트 전파가 시작되었다가, 클릭한 부분까지 오면 다시 버블링이 시작된다!!
1. html(캡처링)
2. body(캡처링)
3. pink(캡처링)
4. purple(캡처링)
5. blue(캡처링)
6. blue(버블링)
7. purple(버블링)
8. pink(버블링)
9. body(버블링)
10. html(버블링)
사용자의 액션에 의해 이벤트 발생 시 이벤트 버블링에 의해 document 레벨까지 버블링 되어 올라가는데 이 작동 방식을 이용해 자식 엘리먼트의 각각에 모든 이벤트를 주지 않고, 부모에게만 이벤트를 위임하는 방법
=> 여러 개의 이벤트 리스너를 등록하지 않고 상위 요소에 하나의 이벤트 리스너만 등록하는 것
<html>
<body>
<!-- 분홍색 -->
<div class="pink" id="container">
<!-- 보라색 -->
<div class="purple">
<!-- 파란색 -->
<div class="blue">
blue
</div>
</div>
</div>
<script>
document.getElementById("container").addEventListener("click", function(event) {
if (event.target.className) {
alert(event.target.className);
}
});
</script>
</body>
</html>
상위 요소에 이벤트 리스너를 추가하고, 하위 요소에서 실제 이벤트가 발생했을때 상위 요소에서 이를 처리하는 것!