What's the difference between event.stopPropagation and event.preventDefault?

后端 未结 7 1282
余生分开走
余生分开走 2020-11-22 00:52

They seem to be doing the same thing...
Is one modern and one old? Or are they supported by different browsers?

When I handle events myself (without framework) I

相关标签:
7条回答
  • 2020-11-22 01:21

    Terminology

    From quirksmode.org:

    Event capturing

    When you use event capturing

                   | |
    ---------------| |-----------------
    | element1     | |                |
    |   -----------| |-----------     |
    |   |element2  \ /          |     |
    |   -------------------------     |
    |        Event CAPTURING          |
    -----------------------------------
    

    the event handler of element1 fires first, the event handler of element2 fires last.

    Event bubbling

    When you use event bubbling

                   / \
    ---------------| |-----------------
    | element1     | |                |
    |   -----------| |-----------     |
    |   |element2  | |          |     |
    |   -------------------------     |
    |        Event BUBBLING           |
    -----------------------------------
    

    the event handler of element2 fires first, the event handler of element1 fires last.

    Any event taking place in the W3C event model is first captured until it reaches the target element and then bubbles up again.

                     | |  / \
    -----------------| |--| |-----------------
    | element1       | |  | |                |
    |   -------------| |--| |-----------     |
    |   |element2    \ /  | |          |     |
    |   --------------------------------     |
    |        W3C event model                 |
    ------------------------------------------
    

    Interface

    From w3.org, for event capture:

    If the capturing EventListener wishes to prevent further processing of the event from occurring it may call the stopPropagation method of the Event interface. This will prevent further dispatch of the event, although additional EventListeners registered at the same hierarchy level will still receive the event. Once an event's stopPropagation method has been called, further calls to that method have no additional effect. If no additional capturers exist and stopPropagation has not been called, the event triggers the appropriate EventListeners on the target itself.

    For event bubbling:

    Any event handler may choose to prevent further event propagation by calling the stopPropagation method of the Event interface. If any EventListener calls this method, all additional EventListeners on the current EventTarget will be triggered but bubbling will cease at that level. Only one call to stopPropagation is required to prevent further bubbling.

    For event cancelation:

    Cancelation is accomplished by calling the Event's preventDefault method. If one or more EventListeners call preventDefault during any phase of event flow the default action will be canceled.

    Examples

    In the following examples, a click on the hyperlink in the web browser triggers the event's flow (the event listeners are executed) and the event target's default action (a new tab is opened).

    HTML:

    <div id="a">
      <a id="b" href="http://www.google.com/" target="_blank">Google</a>
    </div>
    <p id="c"></p>
    

    JavaScript:

    var el = document.getElementById("c");
    
    function capturingOnClick1(ev) {
        el.innerHTML += "DIV event capture<br>";
    }
    
    function capturingOnClick2(ev) {
        el.innerHTML += "A event capture<br>";
    }
    
    function bubblingOnClick1(ev) {
        el.innerHTML += "DIV event bubbling<br>";
    }
    
    function bubblingOnClick2(ev) {
        el.innerHTML += "A event bubbling<br>";
    }
    
    // The 3rd parameter useCapture makes the event listener capturing (false by default)
    document.getElementById("a").addEventListener("click", capturingOnClick1, true);
    document.getElementById("b").addEventListener("click", capturingOnClick2, true);
    document.getElementById("a").addEventListener("click", bubblingOnClick1, false);
    document.getElementById("b").addEventListener("click", bubblingOnClick2, false);
    

    Example 1: it results in the output

    DIV event capture
    A event capture
    A event bubbling
    DIV event bubbling
    

    Example 2: adding stopPropagation() to the function

    function capturingOnClick1(ev) {
        el.innerHTML += "DIV event capture<br>";
        ev.stopPropagation();
    }
    

    results in the output

    DIV event capture
    

    The event listener prevented further downward and upward propagation of the event. However it did not prevent the default action (a new tab opening).

    Example 3: adding stopPropagation() to the function

    function capturingOnClick2(ev) {
        el.innerHTML += "A event capture<br>";
        ev.stopPropagation();
    }
    

    or the function

    function bubblingOnClick2(ev) {
        el.innerHTML += "A event bubbling<br>";
        ev.stopPropagation();
    }
    

    results in the output

    DIV event capture
    A event capture
    A event bubbling
    

    This is because both event listeners are registered on the same event target. The event listeners prevented further upward propagation of the event. However they did not prevent the default action (a new tab opening).

    Example 4: adding preventDefault() to any function, for instance

    function capturingOnClick1(ev) {
        el.innerHTML += "DIV event capture<br>";
        ev.preventDefault();
    }
    

    prevents a new tab from opening.

    0 讨论(0)
  • 2020-11-22 01:22

    stopPropagation stops the event from bubbling up the event chain.

    preventDefault prevents the default action the browser makes on that event.

    Examples

    preventDefault

    $("#but").click(function (event) {
      event.preventDefault()
    })
    $("#foo").click(function () {
      alert("parent click event fired!")
    })
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="foo">
      <button id="but">button</button>
    </div>

    stopPropagation

    $("#but").click(function (event) {
      event.stopPropagation()
    })
    $("#foo").click(function () {
      alert("parent click event fired!")
    })
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="foo">
      <button id="but">button</button>
    </div>

    With stopPropagation, only the button's click handler is called while the div's click handler never fires.

    Where as if you use preventDefault, only the browser's default action is stopped but the div's click handler still fires.

    Below are some docs on the DOM event properties and methods from MDN:

    • event.cancelBubble
    • event.preventDefault()
    • event.returnValue
    • event.stopPropagation()

    For IE9 and FF you can just use preventDefault & stopPropagation.

    To support IE8 and lower replace stopPropagation with cancelBubble and replace preventDefault with returnValue

    0 讨论(0)
  • 2020-11-22 01:26

    This is the quote from here

    Event.preventDefault

    The preventDefault method prevents an event from carrying out its default functionality. For example, you would use preventDefault on an A element to stop clicking that element from leaving the current page:

    //clicking the link will *not* allow the user to leave the page 
    myChildElement.onclick = function(e) { 
        e.preventDefault(); 
        console.log('brick me!'); 
    };
    
    //clicking the parent node will run the following console statement because event propagation occurs
    logo.parentNode.onclick = function(e) { 
        console.log('you bricked my child!'); 
    };
    

    While the element's default functionality is bricked, the event continues to bubble up the DOM.

    Event.stopPropagation

    The second method, stopPropagation, allows the event's default functionality to happen but prevents the event from propagating:

    //clicking the element will allow the default action to occur but propagation will be stopped...
    myChildElement.onclick = function(e) { 
        e.stopPropagation();
        console.log('prop stop! no bubbles!'); 
    };
    
    //since propagation was stopped by the child element's onClick, this message will never be seen!
    myChildElement.parentNode.onclick = function(e) { 
        console.log('you will never see this message!'); 
    };
    

    stopPropagation effectively stops parent elements from knowing about a given event on its child.

    While a simple stop method allows us to quickly handle events, it's important to think about what exactly you want to happen with bubbling. I'd bet that all a developer really wants is preventDefault 90% of the time! Incorrectly "stopping" an event could cause you numerous troubles down the line; your plugins may not work and your third party plugins could be bricked. Or worse yet -- your code breaks other functionality on a site.

    0 讨论(0)
  • 2020-11-22 01:27

    event.preventDefault(); Stops the default action of an element from happening.

    event.stopPropagation(); Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.

    For example, if there is a link with a click method attached inside of a DIV or FORM that also has a click method attached, it will prevent the DIV or FORM click method from firing.

    0 讨论(0)
  • 2020-11-22 01:34

    $("#but").click(function(event){
    console.log("hello");
      event.preventDefault();
     });
    
    
    $("#foo").click(function(){
     alert("parent click event fired !");
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="foo">
      <button id="but">button</button>
    </div>

    0 讨论(0)
  • 2020-11-22 01:38

    Event.preventDefault- stops browser default behaviour. Now comes what is browser default behaviour. Assume you have a anchor tag and it has got a href attribute and this anchor tag is nested inside a div tag which has got a click event. Default behaviour of anchor tag is when clicked on the anchor tag it should navigate, but what event.preventDefault does is it stops the navigation in this case. But it never stops the bubbling of event or escalation of event i.e

    <div class="container">
     <a href="#" class="element">Click Me!</a>
    </div>
    
    $('.container').on('click', function(e) {
     console.log('container was clicked');
    });
    
    $('.element').on('click', function(e) {
      e.preventDefault(); // Now link won't go anywhere
      console.log('element was clicked');
    });
    

    The result will be

    "element was clicked"

    "container was clicked"

    Now event.StopPropation it stops bubbling of event or escalation of event. Now with above example

    $('.container').on('click', function(e) {
      console.log('container was clicked');
    });
    
    $('.element').on('click', function(e) {
      e.preventDefault(); // Now link won't go anywhere
      e.stopPropagation(); // Now the event won't bubble up
     console.log('element was clicked');
    });
    

    Result will be

    "element was clicked"

    For more info refer this link https://codeplanet.io/preventdefault-vs-stoppropagation-vs-stopimmediatepropagation/

    0 讨论(0)
提交回复
热议问题