FE/JavaScript

[JS] DOM - Event Flow

mandelina 2022. 5. 12. 17:52

들어가기에 앞서 , Event Flow 란 ?

이벤트가 발생되면 누가 먼저 이벤트를 실행시켜야 하나? 에대한 답이라 할 수 있다.

이벤트를 실행시키기 위한 흐름을 말한다.

 

 

여기서 propagate라는 단어가 등장한다.

 

 

뜻을 살펴보면 전파하다 라는 뜻이다 .

 

즉 여기선 이벤트가 발생되었을때 이벤트가 전파되는 과정을 알아보겠다.

 


 

한가지 더 알아두어야 할 단어는

event.target 그리고 event.currentTarget이다.

 

event.target  : 이벤트가 발생한 그 지점 ! 즉 곧 보여드릴 예제에선 div를 가리킨다.

event.currentTarget : 이벤트 리스너가 연결된 요소 , 즉 예제에선 흐름에 따라 html,body가 된다.

 

 


 

🚀 Capture phase = propagate up

 

 가장상위인 window객체 -> event.target 로 탐색하며 캡처링 이벤트리스너를 실행

 

 이벤트 함수의 세번째 인자에 boolean값으로 true를 넣으면 캡처링 단계에서 이벤트 발생

 

 

🚀 Bubble phase = propagate down

event.target -> 상위 돔트리로 올라가며 window객체  까지 만나는 버블 이벤트 리스너를 실행

 

이벤트 함수의 세번째 인자에 boolean값으로 false를 넣으면 버블링 단계에서 이벤트 발생

 

 

 

이렇게 Event Flow중 어느 단계에 실행되고 싶은지 선택을 할 수 있다 .

즉 , 캡처냐 버블이냐를 정해줄 수 있다 .

(기본값은 Bubble이다.)

 


 

 

예제에서는  div를 click했을때 Event Flow를 설명하겠다. 

 

[예제1]

<!DOCTYPE html>
<html lang="ko">
<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></title>
</head>
<body>
        <div>div</div>
    <script>

        const html = document.documentElement;
        const body = document.body;
        const div = document.querySelector('div');

        //  캡처링이벤트 
        
        div.addEventListener('click',function(){
            console.log('div');
        })

        body.addEventListener('click',function(){
            console.log('body');
        })

        html.addEventListener('click',function(){
            console.log('html');
        })
    </script>
</body>
</html>

 

 

div를 누르고 console창을 보면 

 

 

 

 

div -> body -> html순으로 뜬다.

왜 ? 이벤트리스너의 3번째 인자에 아무것도 주지 않았으므로 디폴트인 Bubble phase만 거친것이다.

 

 


 

 

그렇다면 이제 코드를 바꿔서, Capture phase Bubble phase 모두 일어나게 해보자 .

 

 

[예제2]

<!DOCTYPE html>
<html lang="ko">
<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></title>
</head>
<body>
        <div>div</div>
    <script>

        const html = document.documentElement;
        const body = document.body;
        const div = document.querySelector('div');

        //  캡처링이벤트 

        div.addEventListener('click',function(){
            console.log('div');
        },true) 
        //사실 여기서 true를 써주지 않아도 div는 다른 자식에 의해 실행될 이유는 없기때문에 굳이 사용할 이유는 없다.

        body.addEventListener('click',function(){
            console.log('body');
        },true)

        html.addEventListener('click',function(){
            console.log('html');
        },true)
        
        div.addEventListener('click',function(){
            console.log('div');
        },)

        body.addEventListener('click',function(){
            console.log('body');
        })

        html.addEventListener('click',function(){
            console.log('html');
        })

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

 

 

 

 

 

 

div를 다시 클릭 했을때 , 

html -> body-> div ->div->body ->html로 찍히는것을 볼 수 있다.

 

이를 그림으로 정리하면,

Capture phase를 거쳐 event.target에 도착 후, Bubble phase 단계를 거치는것을 확인 할 수 있다.

 

 

더해서 이벤트 흐름중 전파를 멈추고 싶을땐 

e.stopPropagation( )

를 사용한다고 한다.

 


마무리

찾아본 결과 실무에서 Event Flow를 사용할 일은 많이 없지만 미세하게 컨트롤 해야하는 상황에서 사용한다고한다. 

 

다만 면접 단골질문이므로 잘 알아두기 ..!!


.

.

.

 

(혹시라도 틀린 부분이 있으면 댓글 부탁드립니다. 🙂 )

 

'FE > JavaScript' 카테고리의 다른 글

[JS] JSON  (0) 2022.05.16
[JS] Prototype  (0) 2022.05.16
[JS] this  (0) 2022.05.11
[JS] 클로저 (Closure)  (0) 2022.05.11
[JS] 구조분해 할당  (0) 2022.05.11