JavaScript/JS 활용 & etc..

[자바스크립트] 이벤트 모델의 전파 과정

jaiyah 2016. 9. 29. 13:02


이벤트 전달을 막는 4가지 방법

이벤트 모델은 DOM의 구조를 두 번 순회합니다. 

이벤트가 호출되면 최상위 루트에서 자식 엘리멘트들을 타고 이벤트 타깃까지 내려가는 캡쳐 단계가 일어나고 다시 반대로 이벤트의 타킷으로부터 최상위 루트까지 올라가는 버블 단계가 일어납니다.

이러한 이벤트 전파 과정을 통해서 예상치 못한 결과가 발생하는 경우가 있는데 예를 들어 부모 요소와 자식 요소 두 곳에 click 이벤트를 생성한 후 자식 요소를 클릭하여 이벤트를 호출할 때 클릭하지 않은 부모 요소에서 클릭이 발생하게 됩니다.

이런 의도치 않은 반응이 일어나 문제가 발생되는 것은 이벤트 모델의 전파과정 중 버블링 단계에서 이벤트를 발생하기 때문입니다.

하지만 event 객체에 stopPropagation() 메소드를 호출하면 이 단계가 진행되지 않도록 사전에 차단할 수 있습니다.




이벤트를 중단할 때 사용되는 방법에 대한 정리는 아래와 같습니다.

event.preventDefault();
// 현재 이벤트의 기본 동작을 중단합니다.


event.stopPropagation();
// 현재 이벤트가 상위로 전파되지 않도록 중단합니다.


event.stopImmediatePropagation();
// 현재 이벤트가 상위뿐 아니라 현재 레벨에 걸린 다른 이벤트도 동작하지 않도록 합니다.


return false;
// jQuery를 사용한 코드내에서는 위의 preventDefault, stopPropagation 두개 모두를 수행한 것과 같고,

// jQuery를 사용하지 않고 return false 를 작성할 경우에는
// event.preventDefault() 와 같습니다.




이벤트 전파란 무엇인가?!

위의 메소드를 알아보기 전에 이벤트가 전파,전달되는 것이 무엇인지에 대해 다음의 예제를 통해 확인해 보도록 하겠습니다.


See the Pen 이벤트 전파 by jaeheekim (@jaehee) on CodePen.




위의 결과 창에서 각 영역을 클릭하면 결과 콘솔에 나타나는 결과가 나타납니다.

가장 최상위의 부모 DIV 를 클릭했을 때는 DIV 만을 클릭한 결과만 나타나지만, 가장 아래에 있는 자식 span 을 클릭할 경우에는 span 뿐만 아니라 p 와 div 의 클릭 이벤트까지 모두 포함하여 동작하는 것을 확인할 수 있습니다.


이것이 이벤트가 전파,전달되는 것입니다.


이러한 이벤트 전달을 차단하기 위해 사용되는 코드가 앞서 설명한 세 가지 코드들입니다.




event.stopPropagation() - 이벤트 전파를 차단


stopPropagation() 은 이벤트가 상위 DOM 으로의 전달,전파를 하지 않도록 하는 코드입니다.


다음의 예제에서는 span 클랙 이벤트에 event.stopPropagation() 메소드를 추가해서 상위 DOM 으로 이벤트가 전달되지 않도록 했습니다.

결과는 span 을 클릭했을 경우에는 span 이벤트만 동작하지만, p 를 클릭했을 때에는 p, div 가 모두 호출되게 됩니다


See the Pen stopPropagation 메소드 by jaeheekim (@jaehee) on CodePen.




event.preventDefault() - 이벤트의 기본 동작을 차단하는 메소드


다음의 예제는 a 태그에 걸린 이벤트 동작을 수행하면서도 a 태그의 본래 목적을 지닌 기능인 URL 이동하는 기능까지 모두 수행하고 있는 것을 확인 하실 수 있습니다.

이 말인 즉슨, 이벤트 동작과 더불어 a 태그가 지닌 기본동작 이벤트도 함께 수행하고 있다는 것입니다.

event.stopPropagation() 메소드로는 이벤트의 전달을 차단만 할 뿐 기본동작인 URL 이동 기능을 막지 못합니다. 


See the Pen preventDefault by jaeheekim (@jaehee) on CodePen.




다음의 예제에서는 stopPropagation() 메소드 대신 preventDefault() 메소드로 변경하여 실행해 보도록 하겠습니다.

동작을 확인해 보면 a 태그의 기본 기능 동작이 실행되지 않는 것을 확인해 보실 수 있습니다.



//DIV 영역에 클릭 이벤트 설정
$("#div_").on("click",function(event){
    $("#console").append("<br>DIV 클릭");
});

//P 영역에 클릭 이벤트 설정
$("#p_").on("click",function(event){
    $("#console").append("<br>P 클릭");
});

//A 영역에 클릭 이벤트 설정
$("#a_").on("click",function(event){
    $("#console").append("<br>A 클릭");
    
    //이벤트의 기본 동작을 중단한다.
    event.preventDefault();
});

See the Pen preventDefault 적용 by jaeheekim (@jaehee) on CodePen.


프로젝트를 수행하다 보면 일반적으로 DOM 에서 본인이 원하는 이벤트 동작만을 수행하고 싶을 때에는 stopPropagation() 과 preventDefault() 두 코드를 사용해야 합니다.

하지만 이벤트 동작을 수행함에 있어 jquery 코드내에서 사용한다면 return false 를 사용하여 두 가지의 이 메소드를 수행한 것과 같은 결과를 나타내게 할 수 있습니다.




stopImmediatePropagation() - 같은 DOM 에 걸린 다른 이벤트까지도 전파를 차단

앞서 살펴 본 stopPropagation() 메소드는 이벤트가 상위 DOM 으로의 전달을 차단하는 코드입니다

그렇다면 해당 DOM 에 여러 개의 이벤트가 함께 걸려있었다면 어떻게 될까?!


다음의 예제에서는 span 클릭 이벤트에 stopPropagation() 메소드를 추가하여 상위 전파를 차단하도록 했습니다.

다른 점이 있다면 span 에 클릭 이벤트를 두 개를 주었다는 점입니다.

그렇다면 이렇게 한 개의 DOM 영역에 여러 개의 이벤트를 걸게되면 stopPopagation 은 어떻게 동작하게 될까요?


결과는 span 을 클릭했을 때, p, div 까지 이벤트가 전달되지는 않지만 span 에 걸린 두 개의 이벤트가 모두 동작하는 것을 볼 수 있습니다.


See the Pen stopImmediatePropagation by jaeheekim (@jaehee) on CodePen.




다음의 코드는 span 에 걸린 두 개의 이벤트 중 첫번째 이벤트에 stopPropagation() 대신 stopImmediatePropagation() 을 사용하도록 하겠습니다.

결과를 확인해 보면 이전 코드에서는 span 에 걸려 있던 두 개의 이벤트가 모두 호출되어 동작되었지만, 지금의 코드는 즉시 전파가 중단되어 첫번째 이벤트만 호출되어 동작되는 것을 확인하실 수 있습니다.


See the Pen stopImmediatePropagation() 적용예제 by jaeheekim (@jaehee) on CodePen.




이벤트 캡처링(event capture)


See the Pen gaeovZ by jaeheekim (@jaehee) on CodePen.




이벤트 버블링(event bubble)


See the Pen 이벤트 버블링 by jaeheekim (@jaehee) on CodePen.



Jaehee's WebClub



[출처] : 감성프로그래밍