본문 바로가기

World Wide Web/jquery

stopPropagation과 preventDefault의 차이점

javascript 에서는, 이벤트를 막기 위해서는 stopPropagation() 과 preventDefault() 를 쓴다.
이전에는 이 이벤트들의 차이를 멋도 모르고 그냥 썼는데, 최근에 우연히 이 둘의 차이를 확실하게 알게 되어 적어 놓는다.
이 둘의 차이는, 사용자가 발생한 이벤트를 막느냐, 기본 이벤트를 막느냐의 차이다.
예를 들어, 이런 코드를 보자.

<div id="div1">
<img src="./image/logo.jpg" id="img1"></img>
</div>
</a>

<script>
document.getElementById('div1').onclick = function(){ alert( 'click div1' ); };
document.getElementById('img1').onclick = function(){ alert( 'click img1' ); };
</script>

사용자가 여기서, 이미지를 클릭한다면 어찌 될까?
아마도 "click img1" 이 alert 로 뜨고, 다음 "click div1" 이 뜨고, 그 다음 www.daum.net 으로 넘어갈 거다.
만일 onclick 함수에서 stopPropargation() 을 쓰면, 사용자의 액션에 의한 이벤트 전파가 막아지므로, "click div1" 의 alert 이 뜨는 걸 막을 수는 있다.
하지만, http://www.daum.net 으로 이동하는 걸 막지는 못한다.

만일 onclick 함수에서 proventDefault() 를 쓰면, 브라우저의 기본 이벤트가 무효화 되므로, Ancher 태그의 hlink 가 작동하지 않는다. 즉http://www.daum.net 으로 이동하지 않는다.
하지만, 사용자 클릭 이벤트 전파는 막지 않으므로, alert() 2번. 'click img1" 과 'click div1"이 둘 다 뜬다.
몰론, stopPropagation() 과 preventDefault() 를 둘 다 쓰면, 둘 다 막겠지.

출처 : http://ckbcorp.tistory.com/401


* event.stopPropagation() 이 왜 필요한가?

   - 상위 엘리먼트의 동일한 이벤트가 호출되는 것을 막기 위하여

   - 만약 TR에 onclick이벤트가 걸려 있고, TABLE에도 걸려있을 경우,
     TR을 클릭하면 TR이벤트 => TABLE이벤트 순으로 이벤트핸들러가 호출되는데.
     이 경우 TABLE이벤트가 trigger되지 않도록 하는 것이 stopPropagation() 이다.



* 참고 

   - 모질라 사이트에 있는 예제를 참고하면 이해가 쉬울 것이다.
      stopPropagation()이 있는 부분을 주석처리 비교하면서 'one' 이 있는 TR을 클릭해 보자

   - jQuery의 .live() 함수 등에서 stopPropagation()이 동작하지 않는 문제 - 댓글 참고




--------------------------------------------------------------------------------------------------

stopPropagation(),  preventDefault() 대신에 jQuery에서는 return false를 하면 두가지가 같이 적용하는 것으로 인식한다.

 

하지만 js에서 return false는 preventDefault()만 한것으로 인식한다.

--------------------------------------------------------------------------------------------------

ab, back space 키 입력시 브라우져의 디폴트 동작을 취소할 수 있다.


    if (event.preventDefault){
        event.preventDefault();
    } else{
        event.returnValue = false;
    }


이벤트가 발생했을 때 상위의 element로 이벤트를 전달하고 싶지 않을 때는 위의
cancelable이나 preventDefault가 아니라 stopPropatation을 사용해 주면 된다.

event.cancelBubble = true; // for IE
if(event.stopPropagation) {
   event.stopPropagation();
}

--------------------------------------------------------------------------------------------------