브라우저는 어떻게 화면 내의 특정 이벤트를 감지할까?? 또 감지한 이벤트를 어떻게 다른 화면에 전파할까??
웹 어플리케이션에서 사용자의 입력을 받기 위한 기능
<button>button<button>
const btn = document.querySelector("button");
btn.addEventListener("click", () => console.log("hello"));
addEventListener()
를 사용하여 사용자의 입력에 따른 추가적인 동작들을 구현할 수 있다.이 때, 브라우저는 이러한 이벤트들을 감지하는 2가지 방법!
이벤트 버블링이란, 특정 화면 요소에서 발생한 이벤트가 상위 요소까지 전달되는 현상을 말한다.
예를 들자면 body>div>div>div 와 같은 구조를 가진 코드가 있다면,
마지막 div에서 발생한 이벤트가 버블링을 통하여 body까지 전달되는 현상을 이벤트 버블링이라 할 수 있다!
<div class="one">
<div class="two">
<div class="three"></div>
</div>
</div>
//js코드
let divs = document.querySelectorAll("div");
divs.forEach(function (div) {
div.addEventListener("click", logEvent);
});
function logEvent(event) {
console.log(event.currentTarget.className);
}
이렇게 가장 하위 요소의 이벤트가 상위 요소로 계속해서 전달되는 것을 이벤트 버블링 이라 한다!
단, 지금은 모든 태그에 이벤트가 걸려있으나 특정 태그에만 이벤트를 건다면 이와같은 결과는 나타나지 않는다!
이벤트 캡쳐는 버블링과 반대되는 현상이다. 상위요소 -> 하위요소로 이벤트 전파
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
div.addEventListener('click', logEvent, {
capture: true // default 값은 false입니다.
});
});
function logEvent(event) {
console.log(event.currentTarget.className);
}
버블링과의 차이점은 이벤트가 발생한 해당 요소를 가장 상위요소에서 부터 찾아내려간다는 점이다! 위의 버블링은 가장 하위 요소의 class name인 three->two->one 순으로 출력이 됐으나, 캡쳐링은 one->two->three로 출력된다.
참고 사이트 에서는 버블링
과 캡쳐링
을 방지하기 위해 stopPropagation을 사용할 수 있다고 나와있다. 이 API는 이벤트의 전파를 막는 용으로 사용되는데, 예기치 못한 버그를 발생시킬 수도 있는 위험성을 가지고 있다. 때문에 무분별한 사용은 조심해야한다!🙂
하위 요소에 이벤트를 일일히 붙이지 않고, 상위 요소에서 이를 제어한다!! 라고 이해
예제를 살펴보쟈!!!!
<div class="container">
<div class="one">
<div class="two">
<div class="three"></div>
</div>
</div>
</div>
//js코드
const divs = document.querySelectorAll("div");
divs.forEach(function (div) {
div.addEventListener("click", (e) => alert(e.currentTarget.className));
});
const container = document.querySelector(".container");
let div = document.createElement("div");
div.setAttribute("class", "four");
container.appendChild(div);
상단의 html 코드를 살펴볼 때, 만약 네번째 class를 js코드에서 추가적으로 삽입한다면 어떻게 될까?
currentTarget.className
이 마지막 추가한 div에는 적용되지 않는다!
이럴 때 사용하는 것이 이벤트 위임!!
위의 코드를 수정해보자!
// const divs = document.querySelectorAll("div");
// divs.forEach(function (div) {
// div.addEventListener("click", (e) => alert(e.currentTarget.className));
// });
const container = document.querySelector(".container");
container.addEventListener("click", (e) => alert(e.currentTarget.className));
let div = document.createElement("div");
div.setAttribute("class", "four");
container.appendChild(div);
container
라는 상위 요소에서 하위 요소들의 이벤트를 통제하는것!
결과는 container
하위의 요소들에 모두 container 라는 alert메세지가 출력되는 것을 볼 수 있다!
버블링 효과를 통해 이같은 결과를 도출해낼 수 있는것.
이 방식을 사용하면 요소가 추가되더라도 하나 하나 이벤트를 붙여줄 필요가 없다!
공부한 자료 : https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/