js 이벤트 전파를 중단하는 네가지 방법

자바스크립트 이벤트 리스너에서 preventDefault()와 stopPropagation() 그리고 return false는 자바스크립트 프로그래밍을 할 때 이벤트 중단을 위해 자주 사용되는 코드들이다.
이벤트 중단 시에 사용되는 방식에 대해서 간단하게 정리하면 아래와 같다.

event.preventDefault()
현재 이벤트의 기본 동작을 중단한다.
event.stopPropagation()
현재 이벤트가 상위로 전파되지 않도록 중단한다.
event.stopImmediatePropagation()
현재 이벤트가 상위뿐 아니라 현재 레벨에 걸린 다른 이벤트도 동작하지 않도록 중단한다.
return false
jQuery를 사용할 때는 위의 두개 모두를 수행한 것과 같고,
jQuery를 사용하지 않을 때는 event.preventDefault()와 같다.
이벤트 전파 예제
먼저 이벤트가 전파되는 것이 무엇인지 아래의 예제를 통해 간단하게 확인해보자.
DIV 영역

P 영역 SPAN 영역

console 창
                                
                                    <div id="div" style="padding:20px;background-color: #848484;color:#fff">
                                        DIV 영역
                                        <p id="p" style="padding:20px;background-color: #666666;color:#fff">
                                            P 영역
                                            <span id="span" style="display:block;padding:20px;background-color: #444444;color:#fff">SPAN 영역</span>
                                        </p>
                                    </div>
                                
                            
                                
                                    var div = document.getElementById("div"),
                                        p = document.getElementById("p"),
                                        span = document.getElementById("span"),
                                        develop1 = document.getElementById("develop1");

                                    // IE8 호환성
                                    if(window.addEventListener){
                                        div.addEventListener("click", function () {
                                            develop1.innerHTML += "div 클릭" + "<br>";
                                        });
                                        p.addEventListener("click", function () {
                                            develop1.innerHTML += "p 클릭" + "<br>";
                                        });
                                        span.addEventListener("click", function () {
                                            develop1.innerHTML += "span 클릭" + "<br>";
                                        });
                                    }else if(window.attachEvent){
                                        div.onclick = function(){
                                            develop1.innerHTML += "div 클릭" + "<br>";
                                        }
                                        p.onclick = function(){
                                            develop1.innerHTML += "p 클릭" + "<br>";
                                        }
                                        span.onclick = function(){
                                            develop1.innerHTML += "span 클릭" + "<br>";
                                        }
                                    }
                                
                            
실제 각 영역을 클릭해가며 콘솔에 나타나는 결과를 확인해보면, 가장 최상위에 있는 DIV를 클릭했을 때는 DIV를 클릭한 결과만 나타나지만,
가장 아래에 있는 SPAN을 클릭할 경우 SPAN 뿐 아니라 P와 DIV의 클릭 이벤트까지도 모두 동작하는 것을 확인할 수 있다.

즉, 이벤트가 전파되는 것이다.

이러한 이벤트 전파를 막기 위해 사용하는 코드가 앞서 위에서 설명한 세 가지 코드들이다.
이제 각각의 코드가 어떻게 다르게 동작하는지 확인해보자.
이벤트의 전파를 막는 event.stopPropagation()
event.stopPropagation() 는 이벤트가 상위 DOM으로 전파되지 않도록 하는 코드이다.
아래의 예제에는 SPAN 클릭 이벤트에 event.stopPropagation()를 추가해서 상위 DOM으로 이벤트가 전파되지 않도록 했다.
결과는 SPAN을 클릭했을 때는 SPAN의 이벤트만 동작하지만, P를 클릭했을 때는 P와 DIV가 모두 호출되게 된다.
참고 : stopPropagation() Event Method는 IE9 이상에서만 적용된다.
DIV 영역

P 영역 SPAN 영역

console 창
                                
                                    <div id="div2" style="padding:20px;background-color: #848484;color:#fff">
                                        DIV 영역
                                        <p id="p2" style="padding:20px;background-color: #666666;color:#fff">
                                            P 영역
                                            <span id="span2" style="display:block;padding:20px;background-color: #444444;color:#fff">SPAN 영역</span>
                                        </p>
                                    </div>
                                
                            
                                
                                    var div2 = document.getElementById("div2"),
                                        p2 = document.getElementById("p2"),
                                        span2 = document.getElementById("span2"),
                                        develop2 = document.getElementById("develop2");

                                    div2.addEventListener("click", function () {
                                        develop2.innerHTML += "div 클릭" + "<br>";
                                    });
                                    p2.addEventListener("click", function () {
                                        develop2.innerHTML += "p 클릭" + "<br>";
                                    });
                                    span2.addEventListener("click", function (event) {
                                        develop2.innerHTML += "span 클릭" + "<br>";
                                        event.stopPropagation();
                                    });
                                
                            
같은 DOM에 걸린 다른 이벤트에도 전파를 막는 event.stopImmediatePropagation()
앞서 살펴본 event.stopPropagation() 는 이벤트가 상위 DOM으로 전파되지 않도록 하는 코드이다.
그렇다면 해당 DOM에 이벤트가 여러개가 걸려있다면 어떻게 될까?

아래의 예제에는 위와 마찬가지로 SPAN 클릭 이벤트에 event.Propagation()을 추가해서 상위 DOM으로 이벤트가 전파되지 않도록 했다.
한가지 다른 점이 있다면 SPAN에 클릭 이벤트를 두개를 주었다는 점이다.
한 개의 DOM에 여러개의 이벤트를 걸었을 때 event.stopPropagation() 은 어떻게 동작할까?

결과는 SPAN을 클릭했을 때, P나 DIV까지 이벤트가 전파되지는 않지만 SPAN에 걸린 두 개의 이벤트 모두가 반응하는 것을 볼 수 있다.
DIV 영역

P 영역 SPAN 영역

console 창
                                
                                    <div id="div3" style="padding:20px;background-color: #848484;color:#fff">
                                        DIV 영역
                                        <p id="p3" style="padding:20px;background-color: #666666;color:#fff">
                                            P 영역
                                            <span id="span3" style="display:block;padding:20px;background-color: #444444;color:#fff">SPAN 영역</span>
                                        </p>
                                    </div>
                                
                            
                                
                                    var div3 = document.getElementById("div3"),
                                        p3 = document.getElementById("p3"),
                                        span3 = document.getElementById("span3"),
                                        develop3 = document.getElementById("develop3");

                                    div3.addEventListener("click", function () {
                                        develop3.innerHTML += "div 클릭" + "<br>";
                                    });
                                    p3.addEventListener("click", function () {
                                        develop3.innerHTML += "p 클릭" + "<br>";
                                    });
                                    span3.addEventListener("click", function (event) {
                                        develop3.innerHTML += "span 클릭1" + "<br>";
                                        event.stopPropagation();
                                    });
                                    span3.addEventListener("click", function (event) {
                                        develop3.innerHTML += "span 클릭2" + "<br>";
                                        event.stopPropagation();
                                    });
                                
                            
자, 이제 SPAN에 걸린 두 개의 이벤트 중 첫 번째 이벤트에 event.stopPropagation() 대신 event.stopImmediatePropagation() 을 사용한 아래의 예제를 살펴보자

이전에는 SPAN 을 클릭하면 SPAN에 걸려있던 두 개의 이벤트가 모두 호출되었지만,
이제는 즉시 전파가 중단되어 첫번째 이벤트만 호출되는 것을 확인할 수 있다.
참고 : stopImmediatePropagation() Event Method는 IE9 이상에서만 적용된다.
DIV 영역

P 영역 SPAN 영역

console 창
                                
                                    <div id="div4" style="padding:20px;background-color: #848484;color:#fff">
                                        DIV 영역
                                        <p id="p4" style="padding:20px;background-color: #666666;color:#fff">
                                            P 영역
                                            <span id="span4" style="display:block;padding:20px;background-color: #444444;color:#fff">SPAN 영역</span>
                                        </p>
                                    </div>
                                
                            
                                
                                    var div4 = document.getElementById("div4"),
                                        p4 = document.getElementById("p4"),
                                        span4 = document.getElementById("span4"),
                                        develop4 = document.getElementById("develop4");

                                    div4.addEventListener("click", function () {
                                        develop4.innerHTML += "div 클릭" + "<br>";
                                    });
                                    p4.addEventListener("click", function () {
                                        develop4.innerHTML += "p 클릭" + "<br>";
                                    });
                                    span4.addEventListener("click", function (event) {
                                        develop4.innerHTML += "span 클릭1" + "<br>";
                                        event.stopImmediatePropagation();
                                    });
                                    span4.addEventListener("click", function (event) {
                                        develop4.innerHTML += "span 클릭2" + "<br>";
                                        event.stopPropagation();
                                    });
                                
                            
현재 이벤트의 기본 동작을 중단하는 event.preventDefault()
event.preventDefault()의 기능에 대해 이해하기 위해 span를 a태그로 변경해서 테스트를 진행해보자.
아래의 예제를 실행해보면, A태그에 걸린 이벤트를 수행하면서도 A태그의 기본 기능인 url로 이동하는 기능까지 모두 수행하고 있는 것을 볼 수 있다.
즉 이벤트와 더불어 기본 동작도 수행하고 있는 것이다.
event.stopPropagation() 코드로는 이벤트의 전파만 막을 뿐 기본 동작인 url 이동 기능을 막지 못하고 있는 것을 알 수 있다.
DIV 영역

P 영역 A 영역 네이버 링크

console 창
                                
                                    <div id="div5" style="padding:20px;background-color: #848484;color:#fff">
                                        DIV 영역
                                        <p id="p5" style="padding:20px;background-color: #666666;color:#fff">
                                            P 영역
                                            <a id="span5" href="https://www.naver.com" target="_blank" style="display:block;padding:20px;background-color: #444444;color:#fff">
                                                A 영역 네이버 링크
                                            </a>
                                        </p>
                                    </div>
                                
                            
                                
                                    var div5 = document.getElementById("div5"),
                                        p5 = document.getElementById("p5"),
                                        span5 = document.getElementById("span5"),
                                        develop5 = document.getElementById("develop5");

                                    div5.addEventListener("click", function () {
                                        develop5.innerHTML += "div 클릭" + "<br>";
                                    });
                                    p5.addEventListener("click", function () {
                                        develop5.innerHTML += "p 클릭" + "<br>";
                                    });
                                    span5.addEventListener("click", function (event) {
                                        develop5.innerHTML += "a 클릭" + "<br>";
                                        event.stopPropagation();
                                    });
                                
                            
위의 예제에서 event.stopPropagation() 대신 event.preventDefault() 코드로 대체한 아래 예제를 실행해보면,
두 코드의 기능 차이가 명확해진다.

a 태그의 기본기능인 url 이동 기능이 실행되지 않는 것을 확인할 수 있다.
참고 : preventDefault() Event Method는 IE9 이상에서만 적용된다.
DIV 영역

P 영역 A 영역 네이버 링크

console 창
                                
                                    <div id="div6" style="padding:20px;background-color: #848484;color:#fff">
                                        DIV 영역
                                        <p id="p6" style="padding:20px;background-color: #666666;color:#fff">
                                            P 영역
                                            <a id="span6" href="https://www.naver.com" target="_blank" style="display:block;padding:20px;background-color: #444444;color:#fff">
                                                A 영역 네이버 링크
                                            </a>
                                        </p>
                                    </div>
                                
                            
                                
                                    var div6 = document.getElementById("div6"),
                                        p6 = document.getElementById("p6"),
                                        span6 = document.getElementById("span6"),
                                        develop6 = document.getElementById("develop6");

                                    div6.addEventListener("click", function () {
                                        develop6.innerHTML += "div 클릭" + "<br>";
                                    });
                                    p6.addEventListener("click", function () {
                                        develop6.innerHTML += "p 클릭" + "<br>";
                                    });
                                    span6.addEventListener("click", function (event) {
                                        develop6.innerHTML += "a 클릭" + "<br>";
                                        event.preventDefault();
                                    });
                                
                            
따라서 일반적으로 해당 DOM에서 내가 원하는 이벤트 동작만을 수행하고 싶을 때에는 보통 event.stopPropagation()과 event.preventDefault() 두 코드를 모두 사용해야 한다.
event.stopPropagation() 과 event.preventDefault() 를 모두 수행한 것과 같은 return false
앞서 예제들을 통해 event.stopPropagation()는 상위 DOM으로 이벤트가 전파되는 것을 막고
event.preventDefault()는 이벤트의 기본 동작을 막는다는 것을 확인했다.
또 event.stopImmediatePropagation()은 상위 DOM뿐 아니라 같은 DOM에 걸린 다른 이벤트도 수행하지 않도록 중단한다는 것을 예제를 통해 살펴보았다.

그런데 jQuery를 사용해서 이벤트를 사용하는 경우 return false를 쓰면, stopPropagation 과 preventDefault 를 모두 수행하는 것과 같은 효과를 얻을 수 있다.

아래 예제에는 A태그에 return false가 추가되어 있는데, 따라서 A영역을 클릭할 경우 기본동작인 url 이동도 하지 않고 P나 DIV로 이벤트 전파도 되지 않는 것을 확인할 수 있다.
참고 : 아래 예제는 javascript로만 만든 것이라 return false가 jQuery처럼 작동 안한다.

javascript 예제
DIV 영역

P 영역 A 영역 네이버 링크

console 창
                                
                                    <div id="div7">DIV 영역
                                        <p id="p7">P 영역
                                            <a id="span7" href="https://www.naver.com" target="_blank">A 영역 네이버 링크</a>
                                        </p>
                                    </div>
                                
                            
                                
                                    var div7 = document.getElementById("div7"),
                                        p7 = document.getElementById("p7"),
                                        span7 = document.getElementById("span7"),
                                        develop7 = document.getElementById("develop7");

                                    div7.addEventListener("click", function () {
                                        develop7.innerHTML += "div 클릭" + "<br>";
                                    });
                                    p7.addEventListener("click", function () {
                                        develop7.innerHTML += "p 클릭" + "<br>";
                                    });
                                    span7.addEventListener("click", function (event) {
                                        develop7.innerHTML += "a 클릭" + "<br>";
                                        return false;
                                    });
                                
                            
jQuery 예제
DIV 영역

P 영역 A 영역 네이버 링크

console 창
                                
                                    <div id="div8">DIV 영역
                                        <p id="p8">P 영역
                                            <a id="span8" href="https://www.naver.com" target="_blank">A 영역 네이버 링크</a>
                                        </p>
                                    </div>
                                
                            
                                
                                    $(document).ready(function () {
                                        $("#div8").on("click", function () {
                                            $("#develop8").append("div 클릭" + "<br>");
                                        });
                                        $("#p8").on("click", function () {
                                            $("#develop8").append("p 클릭" + "<br>");
                                        });
                                        $("#span8").on("click", function () {
                                            $("#develop8").append("a 클릭" + "<br>");
                                            return false
                                        });
                                    })