Event Bubbling and Prevention

When an element receives an event, it passes the received event to its parent, all the way to the window. However, what is actually propagated is the event, not the bound execution function. If the parent does not have a bound event function, even if the event is passed, it will not have any effect, but the event has indeed been passed.
The reason for event bubbling is that the event source itself may not have the ability to handle the event, meaning the function to handle the event is not bound to the event source. The source itself cannot handle the event, so it needs to propagate the event, so that the execution function for handling the event can be triggered.

Example

When clicking the <div> with the id of i3, the browser will sequentially pop up 3 2 1. This is event bubbling. The square is a leaf node, and events operated on it will bubble upwards until the root node.

<!DOCTYPE html>
<html>
<head>
    <title>JS Event Bubbling and Prevention</title>
</head>
<style type="text/css">
    div{
        display: flex;
        justify-content: center;
        align-items: center;
    }
</style>

<body>
    <div id="i1" style="height: 150px;width: 150px;background: red;">
        <div id="i2" style="height: 100px;width: 100px;background: green;">
            <div id="i3" style="height: 50px;width: 50px;background: blue;"></div>
        </div>
    </div>
</body>

<script type="text/javascript">
    document.getElementById("i1").addEventListener('click',(e) => {
        alert(1);
    }) 
    document.getElementById("i2").addEventListener('click',(e) => {
        alert(2);
    })  
    document.getElementById("i3").addEventListener('click',(e) => {
        alert(3);
    })     
</script>
</html>

Application Scenarios

For example, we have 10 <li> tags, each with a uid to differentiate the user's click. Using bubbling means we don't need to bind a click event for each <li>, which can be called event delegation.

<!DOCTYPE html>
<html>
<head>
    <title>JS Event Bubbling and Prevention</title>
</head>
<style type="text/css">
    li{
        cursor: pointer;
    }
</style>

<body>
    <ul id="u1">
        <li uid="0">0</li>
        <li uid="1">1</li>
        <li uid="2">2</li>
        <li uid="3">3</li>
        <li uid="4">4</li>
        <li uid="5">5</li>
        <li uid="6">6</li>
        <li uid="7">7</li>
        <li uid="8">8</li>
        <li uid="9">9</li>
    </ul>
</body>

<script type="text/javascript">
    document.getElementById("u1").addEventListener('click',(e) => {
        alert(e.srcElement.getAttribute('uid'));
    })    
</script>
</html>

Preventing Bubbling

Sometimes we don't want events to bubble and trigger the bound events of the upper-level nodes. In this case, we need to prevent the bubbling of events. The method in the W3C is e.stopPropagation(), while IE uses window.event.cancelBubble = true;.

Note

  • Not all events can bubble. The following events do not bubble: blur, focus, load, unload.
  • Event resolution methods may differ in different browsers, and some do not support the capture type solution, with most browsers defaulting to the bubbling type solution.
  • Preventing bubbling does not prevent the default behavior of the object. For example, when a submit button is clicked, it will submit the form data, requiring the use of e.preventDefault(); to prevent the default behavior, while IE uses window.event.returnValue = false;.

Daily Question

https://github.com/WindrunnerMax/EveryDay