html > body > main > div > span
으로 구성된 HTML 문서에서 span
에 클릭 이벤트가 발생했다고 가정하자.html > body > main > div > span
순으로 루트부터 타겟 요소까지 타고 내려가는 형식으로 전파된다.span > div > main > body > html
으로 전파된다.자바스크립트에서는 DOM 요소에 eventListener를 등록하여 이벤트를 캐치하는데, 이 때 기본값은 버블링이다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
</head>
<body>
Body
<main>
Main
<div>Div<span>Span</span></div>
</main>
<script>
const body = document.querySelector("body");
const main = document.querySelector("main");
const div = document.querySelector("div");
const span = document.querySelector("span");
body.addEventListener("click", function () {
console.log("body");
});
main.addEventListener("click", function () {
console.log("main");
});
div.addEventListener("click", function () {
console.log("div");
});
span.addEventListener("click", function () {
console.log("span");
});
</script>
</body>
</html>
위 코드에서 span 요소를 클릭할 경우
이벤트 버블링 흐름에 따라 span > div > main > body
로 이벤트가 전파되는 것을 확인할 수 있다.
addEventListener
의 세번째 파라미터로 true
를 전달하면 캡처링으로 동작하게 된다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
</head>
<body>
Body
<main>
Main
<div>Div<span>Span</span></div>
</main>
<script>
const body = document.querySelector("body");
const main = document.querySelector("main");
const div = document.querySelector("div");
const span = document.querySelector("span");
body.addEventListener(
"click",
function () {
console.log("body");
},
true
);
main.addEventListener(
"click",
function () {
console.log("main");
},
true
);
div.addEventListener(
"click",
function () {
console.log("div");
},
true
);
span.addEventListener(
"click",
function () {
console.log("span");
},
true
);
</script>
</body>
</html>
body > main > div > span
순서로 이벤트가 전파되었음을 확인할 수 있다.이벤트 리스너가 전달하는 event
객체에는 eventPhase
라는 속성이 존재한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
</head>
<body>
Body
<main>
Main
<div>Div<span>Span</span></div>
</main>
<script>
const body = document.querySelector("body");
const main = document.querySelector("main");
const div = document.querySelector("div");
const span = document.querySelector("span");
body.addEventListener(
"click",
function (event) {
console.log("[" + event.eventPhase + "]" + "body");
},
true
);
main.addEventListener(
"click",
function (event) {
console.log("[" + event.eventPhase + "]" + "main");
},
true
);
div.addEventListener(
"click",
function (event) {
console.log("[" + event.eventPhase + "]" + "div");
},
true
);
span.addEventListener(
"click",
function (event) {
console.log("[" + event.eventPhase + "]" + "span");
},
true
);
body.addEventListener("click", function (event) {
console.log("[" + event.eventPhase + "]" + "body");
});
main.addEventListener("click", function (event) {
console.log("[" + event.eventPhase + "]" + "main");
});
div.addEventListener("click", function (event) {
console.log("[" + event.eventPhase + "]" + "div");
});
span.addEventListener("click", function (event) {
console.log("[" + event.eventPhase + "]" + "span");
});
</script>
</body>
</html>
event.stopPropagation()
메서드를 통해 이벤트 전파를 막을 수 있다.event.stopPropagation()
가 호출되면 이벤트 전파가 멈춰버린다.