JavaScript

[JS] 이벤트 전파 / 이벤트 버블링 / 이벤트 캡처링

PEAZH 2024. 10. 15. 16:09
반응형

이벤트 전파 (Event Phase)

브라우저에서 html 요소에 이벤트가 발생할 때, 이벤트가 전파되는 흐름에 따라 이벤트 버블링이벤트 캡처링이 발생함

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event</title>
</head>
<body> body 영역
    <main> main 영역
        <div> div 영역
            <p> p 영역
                <span>span 영역</span>
            </p>
        </div>
    </main>
</body>
</html>

 

01) 이벤트 버블링 (Event Bubbling)

이벤트 버블링은 이벤트 타깃 요소에서부터 최상위 요소인 html 문서까지 이벤트가 전파되는 것으로,

addEventListener 이벤트는 기본적으로 버블링으로 동작함

<script>
    const $body = document.querySelector('body');
    const $main = document.querySelector('main');
    const $div = document.querySelector('div');
    const $p = document.querySelector('p');
    const $span = document.querySelector('span');

    $span.addEventListener('click', function () {
        console.log('span 태그')
    });
    $p.addEventListener('click', function () {
        console.log('p 태그')
    });
    $div.addEventListener('click', function () {
        console.log('div 태그')
    });
    $main.addEventListener('click', function () {
        console.log('main 태그')
    });
    $body.addEventListener('click', function () {
        console.log('body 태그')
    });
</script>

span 태그를 클릭했을 때 consolg 창 (bubbling)

  • 위의 script 코드를 추가해서 console 창을 확인하면, span 태그를 클릭했을 때 span에서부터 body 태그까지 이벤트가 전파되는 과정을 확인할 수 있음

 

02) 이벤트 캡처링 (Event Capturing)

이벤트 캡처링은 최상위 요소(html)에서 해당 이벤트 타깃 요소까지 이벤트가 전파되는 것으로,

addEventListener 이벤트에 true 값을 설정하여 캡처링으로 변경할 수 있음 (기본값 : false)

<script>
    const $body = document.querySelector('body');
    const $main = document.querySelector('main');
    const $div = document.querySelector('div');
    const $p = document.querySelector('p');
    const $span = document.querySelector('span');

    // capturing
    $span.addEventListener('click', function () {
        console.log('capturing span 태그')
    }, true);
    $p.addEventListener('click', function () {
        console.log('capturing p 태그')
    }, true);
    $div.addEventListener('click', function () {
        console.log('capturing div 태그')
    }, true);
    $main.addEventListener('click', function () {
        console.log('capturing main 태그')
    }, true);
    $body.addEventListener('click', function () {
        console.log('capturing body 태그')
    }, true);
</script>

span 태그를 클릭했을 때 console 창 (capturing)

  • 이벤트 핸들러에 true 값을 추가하면, 최상위 요소부터 이벤트가 전파되는 것을 볼 수 있음

 

03) Event.eventPhase

eventPhase는 이벤트 핸들러에서 현재 평가 중인 이벤트 흐름 단계를 나타내는 것으로, 정수 값을 반환

<script>
    const $body = document.querySelector('body');
    const $main = document.querySelector('main');
    const $div = document.querySelector('div');
    const $p = document.querySelector('p');
    const $span = document.querySelector('span');

    // capturing
    $span.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] capturing span 태그')
    }, true);
    $p.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] capturing p 태그')
    }, true);
    $div.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] capturing div 태그')
    }, true);
    $main.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] capturing main 태그')
    }, true);
    $body.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] capturing body 태그')
    }, true);

    // bubbling 
    $span.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] bubbling span 태그')
    });
    $p.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] bubbling p 태그')
    });
    $div.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] bubbling div 태그')
    });
    $main.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] bubbling main 태그')
    });
    $body.addEventListener('click', function () {
        console.log('['+ event.eventPhase + '] bubbling body 태그')
    });
</script>

span 태그를 클릭했을 때 console 창 (eventPhase)

  • 반환값이 1일 때 : 부모객체를 통해서 타켓 이벤트까지 전달한 경우
  • 반환값이 2일 때 :현재 타켓 이벤트인 경우
  • 반환값이 3일 때 : 타켓 이벤트에서 부모 객체로 전달한 경우

 

04) 이벤트 방지

이벤트를 차단하고 싶을 때 메서드를 사용하여, 이벤트를 막을 수 있음

 

🔻stopPropagation() : 현재 이벤트가 발생한 요소에서 상위 요소로의 전파를 중단함

<script>
    $span.addEventListener('click', function () {
        event.stopPropagation();
        console.log('['+ event.eventPhase + '] bubbling span 태그')
    });
</script>

span 태그를 클릭했을 때 console 창 (stopPropagation)

  • bubbling span 태그에서 이벤트가 중단되어 더 이상 실행하지 않음

 

🔻preventDefault() : 해당 html 요소에 대한 기본 동작을 실행하지 않도록 지정

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event</title>
</head>
<body>
    <a href="http://peazh.tistory.com">블로그 이동</a>
    <script>
        const $a = document.querySelector('a');
        $a.addEventListener('click', function () {
            event.preventDefault();
        })
    </script>
</body>
</html>
  • a 태그의 링크를 클릭했을 때, 원래는 페이지가 이동해야 하지만 메서드를 사용하여 이동하지 않음
반응형