이벤트 버블링(bubbling)

하영·2024년 6월 11일
0

JavaScript

목록 보기
7/29

오늘 공부한 내용은 'bubbling' 과 이를 방지? 멈추는 이벤트까지 정리해보려 한다.

bubbling

버블링을 이론적으로 딱딱하게 설명해보자면,
한 요소에서 이벤트가 발생하면 할당된 핸들러가 동작하고 그 위에 있는 부모요소의 핸들러까지 실행된다.
부모요소 뿐만 아니라 최상단에도 이벤트가 할당되어 있다면 이를 만날 때까지 반복해서 이벤트가 실행된다.

노잼이니까 수업 때 본 코드를 보도록 하자!

<section onclick="alert('section  clicked!')">
        <p onclick="alert('p tag clicked!')">
            I am P Tag.
            <button onclick="alert('button clicked!')">Click</button>
        </p>
</section>

인라인 이벤트로 모든 태그에 onclick 이벤트를 부여해서 경고창이 뜨게 만들었다.
section > p > button 순으로!

이 코드의 문제점은 가장 자식요소인 button을 클릭하게 되면
1. button 의 alert 창이 뜨고
2. p 의 alert 창이 뜨고
3. section의 경고창까지 연달아서 뜬다.

이것이 바로 버블링이라고 한다.
이를 막기 위해서는 이벤트를 실행하고자 하는 요소를 정확하게 선택했는지 확인해야 하는데 event.target이 그 역할을 한다.



event.target

부모요소의 핸들러는 정확히 어디서 발생했는지 정보를 알 수 있다.
target은 이벤트가 발생한 가장 안 쪽 요소이므로 event.target 를 사용하면 된다.

html

<div id="container">
        Click To Hide
        <button id="changeColor">Change Color</button>
</div>

위 html로 2가지 이벤트를 실행하려고 한다.

  1. 버튼을 누르면 색이 랜덤으로 변하게 만들기
  2. container를 누르면 숨겨지게 만들기

⭐️ container 안에 button이 있어 버블링이 될 수 있다는 걸 주의해야한다.


javascript

const button = document.querySelector('#changeColor');
const container = document.querySelector('#container');


button.addEventListener('click', function (e) {
    container.style.backgroundColor = makeRandColor();
})


container.addEventListener('click', function () {
    container.classList.toggle('hide');
})

const makeRandColor = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
}
  1. button, container를 변수로 담기
  2. button 을 클릭하면 container의 배경 색이 랜덤으로 바뀌게 이벤트 만들기
  3. container 를 클릭하면 "display: none" 이 실행되는 hide라는 클래스를 toggle 하기
  4. makeRandColor 는 색상 rgb 값을 랜덤으로 만들어주는 함수

얼핏 코드만 보면 문제없어 보이지만 앞서 본 것처럼 container 안에 button이 있어 버블링이 되어 버튼을 클릭해도 hide 된다.

이를 막기 위해서는 e.stopPropagation(); 을 작성해주어야 한다.

e.stopPropagation()

특정 이벤트를 처리하는 핸들러가 여러 개 일 때, 하나가 버블링을 멈춰도 다른 요소의 이벤트에는 영향을 미치지 않는다.

⭐️ 위쪽으로 일어나는 버블링은 막아주지만 다른 핸들러가 동작하는건 막지 못한다.


e.stopPropagation(); 를 추가한 최종 스크립트

const button = document.querySelector('#changeColor');
const container = document.querySelector('#container');


button.addEventListener('click', function (e) {
    container.style.backgroundColor = makeRandColor();
  	e.stopPropagation(); // 버블링 stop 해줌
})


container.addEventListener('click', function () {
    container.classList.toggle('hide');
})

const makeRandColor = () => {
    const r = Math.floor(Math.random() * 255);
    const g = Math.floor(Math.random() * 255);
    const b = Math.floor(Math.random() * 255);
    return `rgb(${r}, ${g}, ${b})`;
}

e.stopPropagation(); 를 추가해줘서 버튼을 클릭하면 색이 바뀌고, 글씨 container를 클릭하면 사라지게 만들었다.

추가로 공부해야할 부분은 event.stopImmediatePropagation() 인데 버블링과 요소에 할당된 다른 핸들러 동작까지 모두 막을 때 사용해야한다.


좋아보이지만 꼭 필요한 경우가 아닌 경우 버블링을 막지 않도록해야한다.
버블링을 막을 일은 거의 없다고 하는데 그래도 알아두면 좋을 것 같아서 정리해보았다. this를 활용하 방법도 추가해서 공부해야할 것 같다..!


출처 : https://ko.javascript.info/bubbling-and-capturing

profile
왕쪼랩 탈출 목표자의 코딩 공부기록

0개의 댓글

관련 채용 정보