안녕하세요 이번 글에선 이벤트 버블링에 대해 알아보겠습니다.
이벤트버블링을 모를 경우 발생하는 예기치못한 이벤트를 살펴보고 어떻게 해결해야 하는지도 확인해보도록 하겠습니다.
이벤트 버블링이란
이벤트 버블링은 이벤트가 가장 안쪽의 대상 요소에서 먼저 트리거된 다음 가장 바깥쪽 DOM 요소 또는 문서 개체에 도달할 때까지 동일한 중첩 계층에서 대상 요소의 상위 요소에서 연속적으로 트리거되는 DOM 이벤트 전파 유형입니다. 이벤트가 브라우저에서 처리되는 한 가지 방법입니다.
- 위키백과 -
즉, 특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미합니다.
이벤트 캡쳐란
이벤트 버블링과 반대되는 현상을 의미합니다.
즉, 브라우저로부터 이벤트가 발생한 요소까지 이벤트를 전달합니다.
우선 이벤트 버블링과, 캡쳐는 이벤트 등록에의해 발생하는데요.
이벤트 등록이란 웹 애플리케이션에서 사용자의 입력을 받기 위해 필요한 기능을 말합니다.
이벤트 버블링 예시
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="script.js" defer></script>
<title>Document</title>
</head>
<body>
<button>add one item</button>
</body>
</html>
var button = document.querySelector("button");
button.addEventListener("click", addItem);
function addItem(event) {
console.log(event);
}
addEventListenr() 웹 api는 웹 개발자들이 화면에 동적인 기능을 추가하기 위해 자연스럽게 사용하는 기능입니다.
그렇다면 브라우저는 어떻게 이벤트 발생을 감지했을까요?
이벤트 버블링과 캡쳐로 이벤트를 감지합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="script.js" defer></script>
<title>Document</title>
</head>
<body>
<div class="one">
<div class="two">
<div class="three">three</div>
</div>
</div>
</body>
</html>
var divs = document.querySelectorAll("div");
divs.forEach(function (div) {
div.addEventListener("click", logEvent);
});
function logEvent(event) {
console.log(event.currentTarget.className);
}
제일 마지막 div인 three를 클릭했지만 콘솔창에는 세 가지 div의 이벤트가 모두 출력됩니다.
이런 현상이 발생하는 이유는 브라우저가 이벤트를 감지하는 방식 때문인데요.
브라우저는 특정 화면 요소에서 이벤트가 발생했을 때 그 이벤트를 최상위에 있는 화면 요소까지 이벤트를 전파시킵니다.
따라서 three -> two -> one 순서로 div 태그에 등록된 이벤트들이 실행됩니다.
이를 이와 같은 현상을 이벤트 버블링이라고 부릅니다.
이벤트 캡쳐 예시
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="script.js" defer></script>
<title>Document</title>
</head>
<body>
<div class="one">
<div class="two">
<div class="three">three</div>
</div>
</div>
</body>
</html>
var divs = document.querySelectorAll("div");
divs.forEach(function (div) {
div.addEventListener("click", logEvent, {
capture: true,
});
});
function logEvent(event) {
console.log(event.currentTarget.className);
}
이벤트 버블링 예시와 코드 차이는 addEventListener에서 3번째 인자로 {capture:true}를 포함시켰다는 것 입니다.
결과는 버블링과 반대로 one,two,three를 출력합니다.
버블링과 캡쳐를 막는 방법, stopPropagation()
위와 같은 이벤트를 막기위해 stopPropagation()을 사용합니다.
var divs = document.querySelectorAll("div");
divs.forEach(function (div) {
div.addEventListener("click", logEvent);
});
function logEvent(event) {
event.stopPropagation();
console.log(event.currentTarget.className);
}
var divs = document.querySelectorAll("div");
divs.forEach(function (div) {
div.addEventListener("click", logEvent, {
capture: true,
});
});
function logEvent(event) {
event.stopPropagation();
console.log(event.currentTarget.className);
}
위와 같이 event.stopPropagation()을 사용하면 클릭한 div의 이벤트만 출력해줍니다.
다음 글에선 react에서 발생할 수 있는 이벤트 버블링과 캡쳐를 살펴보도록 하겠습니다.
'JavaScript' 카테고리의 다른 글
--dev, -D 같은 devDependency를 왜 사용할까? (0) | 2022.12.16 |
---|---|
리액트 a태그에 target='blank'를 적용하면 생기는 에러 (0) | 2022.12.11 |
자바스크립트 reduce에 대해 알아보고 예시를 살펴보자 (0) | 2022.12.03 |
자바스크립트 map에 대해 알아보고 간단한 예시를 살펴보자 (0) | 2022.12.02 |
API란 무엇이고 어떻게 호출할까? (0) | 2022.11.27 |