[HTML | CSS | JavaScript | jQuery] 정리/JavaScript

JavaScript - 이벤트 버블링, Event Bubbling

쎈코 2023. 5. 7. 21:16

이벤트 버블링(Event Bubbling)
         vs 이벤트 터널링(Event Tunnerling), 이벤트 캡쳐링(Event Capturing)

- 자바스크립트는 기본적으로 이벤트 버블링만 발생한다.
- 단, 원하면 이벤트 터널링도 발생시킬 수 있다.

 


이벤트 버블링 : 이벤트가 발생한 요소에서 시작하여 부모 요소를 거슬러 올라가며 이벤트를 처리하는 방식 > 부모 요소에서도 이벤트 처리 가능

하 -> 상순으로 명령이 올라가면서 한 바퀴 돎 > 기본으로 쓰임

<-> 
이벤트 터널링 : 이벤트가 발생한 요소에서 시작하여 자식 요소를 순차적으로 탐색하며 이벤트를 처리하는 방식 > 
부모 요소에서 이벤트 처리 불가능

클릭된 당사자에게 바로 통지가 되는게 아니라 계층구조에 의해 상 -> 하순으로 명령이 내려가면서 알림

         > 이벤트 실행 X > 다시 거꾸로 올라가면서 한바퀴 돌면서 이벤트 실행 O

        
모든 이벤트는 발생할 때마다 계층구조를 한 바퀴 돎 
        
ex) p1이 클릭됐을 시 순서
- 운영체제 > 브라우저에 클릭당했다 알림
- 브라우저 > 클릭된 문서 확인 > html에 클릭당했다 알림
- html > body에 클릭당했다 알림
- body > p1(당사자)에 클릭당했다 알림
- p1 > 당사자임을 확인하고 event 실행
- p2
- p3
※ (★)유턴 시 event 발생 주체에서 유턴함(그 뒤의 함수들은 거치지 않음)


<!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">
    <title>Document</title>
    <style>
         .box {
            padding: 50px;
        }

        #p1 {
            background-color: tomato;
        }

        #p2 {
            background-color: yellow;
        }

        #p3 {
            background-color: skyblue;
        }

    </style>
</head>
<body>
    
    <div id="p1" class="box">
        <div id="p2" class="box">
            <div id="p3" class="box">

            </div>
        </div>
    </div>

    <script>

        const p1 = document.getElementById('p1');
        const p2 = document.getElementById('p2');
        const p3 = document.getElementById('p3');


        p1.onclick = function() {

             빨간색을 클릭했을 때
            // alert('빨강' + event.target.id);
            alert('빨강' + event.currentTarget.id);
        };  // 실행 시 빨강 alert창 뜸

        p2.onclick = function() {
            파란색을 클릭했을 때
            // alert('노랑'
            //          + event.target.id             //p3. 유턴하는 객체(★★★★★)
            //          + event.srcElement.id    //p3p3. 유턴하는 객체
            //          + this.id);                        //p3p3p2. onclick 객체 반환
            // alert(event.currentTarget.id);  //this와 동일(★★★★★)
             => 부모자식이 겹쳤을 때 겹쳐있는 자식 영역을 클릭 시 이 의미를 정확히 알아야 함
            // alert('노랑' + event.target.id);
            alert('노랑' + event.currentTarget.id);
        };   // 실행 시 노랑 - 빨강 alert창 뜸

        p3.onclick = function() {
            // alert('파랑' + event.target.id);    //색깔은 바뀌지만 id는 계속 p3
            alert('파랑' + event.currentTarget.id);  
            //버블링 : 파랑 > 노랑 > 빨강 순으로 alert창 생성됨

            이벤트 버블링을 여기서 중단해라!!
            - 이벤트가 일어났단 사실을 부모님들에게 알리지 마라
            event.cancelBubble = true;
            // 파랑 누르면 버블링이 멈추기 때문에 파랑만 뜨고 끝
            // 하지만 파랑(p3)에만 event를 걸었기 때문에 노랑은 여전히 bubble 진행 
        };  //실행 시 파랑 - 노랑 - 빨강 alert창 뜸  


        이벤트 터널링 구현(DOM 방식으로만 구현 가능)
        p1.addEventListener('click', function() {
            alert('빨강');
        }, true);   //false > 버블링 / true > 터널링

        p2.addEventListener('click', function() {
            alert('노랑');
        }, true);
        //노랑을 누르면 빨강 > 노랑 순으로 alert창 생성
        
        p3.addEventListener('click', function() {
            alert('파랑');
        }, true);
        //파랑을 누르면 빨강 > 노랑 > 파랑 순으로 alert창 생성
        // true로 변경 시 => 아까의 이벤트 버블링 순서의 역순으로 alert 실행(이벤트 터널링)
        //여전히 파랑에서 유턴하는 건 맞지만 내려갈 때 실행 > 올라갈 때 실행 X로 바뀜

        //이벤트 버블링
        p1.addEventListener('click', function() {
            alert('빨강');
        },);  

        p2.addEventListener('click', function() {
            alert('노랑');
        },);

        p3.addEventListener('click', function() {
            alert('파랑');
        }, );
        //false / true 생략하면 디폴트 : false(이벤트 버블링)



    </script>
</body>
</html>