본문 바로가기

JavaScript

[JS] DOM & EVENT #6 이벤트 버블링, 이벤트 위임

1. 이벤트 버블링

 

모든 요소에 클릭 이벤트 발생시 콘솔로그를 찍도록 만들어보자.

  • 아래는 html코드이다. 이런식으로 짰구나만 생각하고 따라오면 된다.
  • 첨부된 css style sheet의 내용은 생략하겠다.

✏️입력

<!DOCTYPE html>
<html>
  <head>
    <title>Welcome</title>
  	<link href="../style.css" type="text/css" rel="stylesheet" />
  </head>
  <body>
    <div id="box">
        <ul id="list">
            <li id="color">Red</li>
        </ul>
    </div>
    <script>
        const box = document.getElementById("box");
        const list = document.getElementById("list");
        const color = document.getElementById("color");

        document.body.addEventListener("click", () => {
            console.log("1. body");
        });
        document.body.addEventListener("click", () => {
            console.log("2. div");
        });
        document.body.addEventListener("click", () => {
            console.log("3. ul");
        });
        document.body.addEventListener("click", () => {
            console.log("4. li");
        });
    </script>
  </body>
</html>

결과

 

  •  li를 클릭해보면  li, ul, div, body순으로 찍힌다.
  • 초록색 네모박스를 클릭하면 자기 자신인 div와 부모요소인 body 모두 console에 남겨진다.

 

✅알 수 있는 것

  • 자식요소에서 발생한 이벤트는 부모와 그 부모를 통해 전파된다.
  • 하위요소에서 상위요소로 올라가는것.
  • 더 이상 부모요소가 없을 때까지 이 과정은 반복된다.

 

 

  • li에서 click 이벤트가 발생하면 부모요소로 전파된다. 이벤트가 거슬러 올라가는 모습이 거품처럼 보인다 해서 이것을 이벤트 버블링(event bubbling)이라고 불린다.
  • 대부분의 이벤트는 버블링으로 전파되지만 일부는 그렇지 않다.  여기서 일부focusblur를 예시로 들 수 있다. 따라서 아래와 같이 바꿔야한다.

 

왼쪽과 오른쪽의 이벤트는 동작은 같으나, 버블링에서 차이가난다.

 

 

예시1) focus 혹은 blur이벤트 발생시, log에 나타내보자.

✏️입력

  • <body> - <div> - <input> 태그가 있다.
  • 각 요소들은 focus이벤트 발생하거나 blur이벤트가 발생할 때 log를 찍어준다.

✨결과

  • input 창에 포커스를 하면 3. input만 찍힌다.

 

포커스를 벗어나도 똑같이 3.input만 찍힌다.

이때, focusfocusin으로, blurfocusout으로 바꿔보자.

 

 

✏️입력

✨결과

3. input, 2. div, 1. body 순서로 찍혔다. 

focus가 벗어나도 부모 요소가 찍히는 것을 볼 수 있다.

 

 

 

📍이벤트 버블링 막는법 

  • 이벤트 버블링은 인위적으로 막을 수 있다.
  • event.stopPropagation(); 을 실행하기

✏️입력

✨결과

  • focusin을 했지만 이벤트버블링이 발생되지 않았다. focusout 도 마찬가지(이건 생략하겠다)
  • 이벤트 버블링 막는 경우는 많이 없기때문에 자주 사용하지는 않는다.

 

 

 


2. 이벤트 위임

  • 자신에게 발생한 이벤트를 다른 요소에서 처리하는 것!
  • 버블링을 사용해서 위임할 수 있다.

✏️입력

📍코드해석

  • <li>가 4개가 있고 클릭을 하면 빨간색으로 바뀌는 코드를 작성했다.
  • clickHandler라는 함수가 있고 그 안에 모든 <li>에 "on"class를 제거하고 클릭된 <li>에 "on"class를 추가해주고있다.
  • clickHandler는 li의 각각 등록되고 있다. (하단 document에 있는 부분)

 

✨결과

문제점

  • 지금은 <li>가 4개지만 숫자가 100개 200개가 된다면? 하나하나 추가,수정하는등의 유지보수가 힘들것이다.  
  • 이럴 땐 li가 아닌 부모요소인 ul에 이벤트를 위임할 수 있다.

✏️입력

  • 이 한 줄만 있으면된다. 100개 200개가 돼도 코드 수정이 필요없다.
  • <li>에서 발생한 이벤트가 <ul>에 등록돼 부모요소에 등록된 이벤트 핸들러를 실행시켜주기 때문이다.
  • 그리고 코드를 다시 작성해봤다.

 

✏️입력

왼쪽은 전, 오른쪽은 수정 후

   event.target

: 이벤트를 발생시키는 요소

   event.currentTarget

: 이벤트 핸들러가 등록된 요소

: 지금은 ul에 이벤트를 등록해두었다.

 

 

이벤트 위임을 사용하지 않았다면 target과 currentTarget은 동일했을 것이다.

하지만 이렇게 했을때 ul (주황색부분)을 누르면 빨간색으로 바뀐다.

따라서 함수에 조건을 추가해줘야한다.

 

✏️입력

  • 주황색 부분을 클릭해도 더이상 빨간색으로 바뀌지않는다.