power-girl0-0

이벤트 전파(버블링과 캡처링) 본문

언어/Javascript

이벤트 전파(버블링과 캡처링)

power-girl0-0 2021. 2. 10. 17:30
728x90

 

생활코딩 웹브라우저 javascript를 참고하여 공부하였습니다.

스스로 공부한 것을 정리하고 복습하기 위한 목적으로 작성하였습니다.

( 출처 :  https://opentutorials.org/course/743inf.run/pBzy)


 이벤트 전파 

HTML 태그는 중첩되어 있다.

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


 캡처링 ( capturing ) 

이런 경우 중첩된 태그들에 이벤트가 등록 되어 있다면 어떻게 처리 될까?

아래 소스를 통해 알아보자.(실행 결과)

[ 실행결과 ]

INPUT HTML capturing
INPUT BODY capturing
INPUT FIELDSET capturing
INPUT INPUT target

이벤트가 부모에서부터 발생해서 자식으로 전파되고 있다.

이러한 방식을 capturing(캡쳐링)이라고 한다.

하지만 ie 낮은 버전에서는 작동하지 않기 때문에 많이 사용하지는 않는다는 것을 알고 있어야 한다.


아래는 위 소스 중 일부이다.

   <body>
   
	<fieldset>
            <legend>event propagation</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>

handler함수에 대해서 살펴보자.

함수가 실행되면, 콘솔 창에 3가지 인자가 출력된다.

 

위 소스에서 첫번째 인자는 input값을 리턴하고 있다.

왜냐하면, 이벤트 핸들러가 중첩되어 있는 태그들을 있다고 하더라도, event.target에 저장되어 있는 값은 언제나 가장 깊은 곳에 있는 element가 된다.

따라서, fieldset태그에서도 event.target은 fieldset태그에 속해있는 input태그가 되는 것이다.

 

두번째 인자는 이벤트 타겟을 의미한는 것이다.

즉, 현재 실행되고 있는 이벤트 핸들러가 어떤 element의 소속인지 알려주는 정보이다.

 

세번재 인자는 아래에서 더 알아보도록 하자.


 버블링 ( bubbling ) 

코드를 아래와 같이 변경해보자. (실행 결과)

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);

위 코드와 차이점은 addEventListener의 3번째 인자가 false로 변경 되었다.


[ 실행결과 ]

INPUT INPUT target
INPUT FIELDSET bubbling
INPUT BODY bubbling
INPUT HTML bubbling

이번에는 순서가 반대로 되었된 것을 확인할 수 있다.

즉, 3번째 인자는 캡쳐링을 의미한 것을 알 수 있다.

 

이처럼 캡쳐링의 반대인 자식부터 부모로 이벤트가 전파되는 것을 버블링(bubbling)이라고 한다.

이는 이벤트 전파를 중간에 가로막을 수도 있다.


이벤트 전파를 중간에 가로막는 소스 코드이다. (실행 결과)

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);

[ 실행결과 ]

INPUT INPUT target
INPUT FIELDSET bubbling
INPUT BODY bubbling

event.stopPropagation()을 사용하여서 이벤트 전파를 막은 것으로, event라는 인자값을 받아와서 body이후의 이벤트는 전파되지 않도록 한 것이다.

 

참고로 ie9 이전의 브라우저에서는 이벤트 전파을 막기 위해서 event.cancelBubble 프로퍼티를 사용해야 한다.

 

 

 

728x90

'언어 > Javascript' 카테고리의 다른 글

[ 이벤트 타입 ] 폼 (form)  (0) 2021.02.10
기본동작의 취소  (0) 2021.02.10
addEventListener( )  (0) 2021.02.10
프로퍼티 리스너  (0) 2021.02.10
inline ( 인라인 방식 )  (0) 2021.02.10
Comments