본문 바로가기
프로그래밍 개발/JS 웹

Javascript 이벤트 전파 - 버블링과 캡처링

by Jinseok Kim 2020. 11. 23.
반응형

 

 

이벤트 중첩에 대하여

 

 

 

HTML 태그는 중첩되어 있다. 따라서 특정한 태그에서 발생하는 이벤트는 중첩되어 있는 태그들 모두가 대상이 될 수 있다.

 

 

 

 

 

 

 

 

만약 중첩된 HTML 태그들에 이벤트가 등록 되어 있다면 중첩된 이벤트가 어떻게 처리 되는지 확인 할 수있다.

<!DOCTYPE html>
<html>
    <head>
          <meta charset="utf-8"/>
        <style>
            html{border:5px solid red;padding:30px;}
            body{border:5px solid green;padding:30px;}
            fieldset{border:5px solid blue;padding:30px;}
            input{border:5px solid black;padding:30px;}
        </style>
    </head>
    <body>
        <fieldset>
            <legend>이벤트 전파</legend>
            <input type="button" id="target" value="target">          
        </fieldset>
        <script>
        function handler(event){
            var phases = ['capturing', 'target', 'bubbling']
            console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
        }
        document.getElementById('target').addEventListener('click', handler, true);
        document.querySelector('fieldset').addEventListener('click', handler, true);
        document.querySelector('body').addEventListener('click', handler, true);
        document.querySelector('html').addEventListener('click', handler, true);
        </script>
    </body>
</html>

  • 위의 코드의 결과를 보면 제일 부모인 HTML부터 차례대로 깊숙이 들어가 taget까지 전파되는 것을 확인 할 수 있다.
  • 이렇게 이벤트가 부모에서부터 발생해서 자식으로 전파되고 있는 방식을 캡처링(capturing)이라고 한다.
  • ie 낮은 버전에서는 작동하지 않기 때문에 많이 사용하지는 않는다.
  • ※ 위 코드에서 this.nodeName의 this는 이벤트 헨들러handler의 함수를 호출하게 한 이벤트 타겟인 버튼 input 태그 값을 의미하는 것으로 볼 수 있다.
  • eventphase-1 프로퍼티는 이벤트 헨들러인 handler 함수가 호출될 때 만약 capturing의 와중에서 호출된 것이면 숫자 1을 나오게 하여 var phases = ['capturing', 'target', 'bubbling']의 배열의 순서에 따라 'capturing'이 리턴하게 되는 원리이다.

 

 

 

 

위의 똑같은 코드 중 아래와 같이 addEventLister의 세 번째 인자인 true을 false로 바꾸면 전파 방향이 반대로 나오는 것을 확인 할 수있다.

document.getElementById('target').addEventListener('click', handler, false);
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', handler, false);
document.querySelector('html').addEventListener('click', handler, false);

이처럼 캡처링과 다르게 자식부터 부모로 이벤트가 전파되는 것을 버블링(bubbling)이라고 한다.

 

 

 

 

 

 

 

 

또 추가하자면 event.stopPropagation()을 아래와 같이 코드를 변경하면 버블링, 캡쳐링 중단하게 할 수 있다.

<script>
        function handler(event){
    var phases = ['capturing', 'target', 'bubbling']
    console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
}
function stophandler(event){
    var phases = ['capturing', 'target', 'bubbling']
    console.log(event.target.nodeName, this.nodeName, phases[event.eventPhase-1]);
    event.stopPropagation();
}
document.getElementById('target').addEventListener('click', handler, false);
document.querySelector('fieldset').addEventListener('click', handler, false);
document.querySelector('body').addEventListener('click', stophandler, false);
document.querySelector('html').addEventListener('click', handler, false);
        </script>

  • 중단시키고자 하는 부분에 addEventListener의 두 번째 인자에 새로 만든 이벤트 헨들러 함수 stophandler을 넣어주었다.
  • 결과값을 보면 stophandler 함수를 넣어준 body 부분에서 캡쳐링 이벤트 전파가 중단 된 것을 볼 수 있다.

 

 

 

 

 

 

 

반응형

댓글