Event bubbling and event capture are almost opposite event flow schemes proposed by the IE and Netscape development teams, respectively. The event flow describes the order in which the page receives events.

The event bubbling

  • The IE event stream is called event bubbling because events are defined to start with a specific element (the deepest node in the document tree) and propagate up to a less specific element (the document).

  • For example, there is an HTML page like this:

    <! DOCTYPE html><html>
    <head>
        <title>Event Bubbling Example</title>
    </head>
    <body>
        <div id="myDiv">Click Me</div>
    </body>
    </html>
    Copy the code

    After clicking on the

    element on the page, the click events occur in the following order: (1)

    (2) (3) < HTML > (4) document

Event capture

  • The Netscape team came up with an alternative calledEvent captureStream of events. Event capture meansThe least specific nodeShould be the first to receive the event, andThe most specific nodeThe event should be received last. Click if the previous example used event capture<div>Elements fire click events in the following order:

    (1) document

    (2) <html>

    (3) <body>

    (4) <div>

DOM event standard

  • In 2002, the W3C published a standard called DOM Level 2 Events Specification stating that browsers should support both call sequences.
  • The DOM event standard describes the three stages of event propagation:
    1. Capture phase – Events (from Window) approach elements down.
    2. Target phase – The event reaches the target element.
    3. Bubble phase – Events bubble up from elements.

    Here’s an example: Click, and the event travels down the ancestral chain to the element (capture phase), then to the target (target phase), and finally up (bubble phase), calling handlers along the way (execute if there are handlers, skip if there aren’t).

AddEventListener binds the event API

  • AddEventListener takes three parameters

    element.addEventListener(event, function.useCapture)
    Copy the code
    • eventEvent name, which supports all DOM events.
    • function: (required) Specifies the function to execute when the event is fired.
    • useCapture: (Optional) Specifies whether the event is executed in the capture or bubble phase. True, capture; Falsy value, bubbling; The default value is false.
  • Event handlers added via addEventListener can only be removed using removeEventListener and passing in the same parameters as when they were added.

    let btn = document.getElementById("myBtn")
    
    // Cannot be removed
    btn.addEventListener("click".() = > {
        console.log(this.id)
    }, false);
    
    
    // It can be removed
    let handler = function() {
        console.log(this.id)
    }
    btn.addEventListener('click', handler, false);
    btn.removeEventListener('click', handler, false);
    Copy the code

Examples and summaries

  • Chestnut 1

    <div id="box1">
        <div id="box2">
            <div id="box3">hello</div>
        </div>
    </div>
    <script>
        box1.onclick = function () {
            console.log("box1 51561");
        };
    
        box2.onclick = function () {
            console.log("box2");
        };
    
        box3.onclick = function () {
            console.log("box3");
        };
    
        box1.onclick = function () {
            console.log("box1");
        };
    
        box1.addEventListener("click".function () {
            console.log("Box1 capture phase");
        },true);
    
        box2.addEventListener("click".function () {
            console.log("Box2 capture phase");
        },true);
    
        box1.addEventListener("click".function () {
            console.log("Box1 bubble phase");
        },false);
    
        box2.addEventListener("click".function () {
            console.log("Box2 bubble stage");
        },false);
    
        box3.addEventListener("click".function () {
            console.log("Box3 bubble stage");
        },false);
    
        box3.addEventListener("click".function () {
            console.log("Box3 Capture phase");
        },true);
    </script>// What does the console output? // Box1 capture stage // Box2 capture stage // Box3 capture stage //box3 bubble stage //box2 bubble stage //box1 bubble stageCopy the code
  • Chestnut 2

    <div id="div1">
        <button>Click on the I</button>
    </div>
    <script>
        div1.addEventListener("click".() = > {
            console.log("div clicked!");
        },true);
    
        let btn = document.querySelector("button");
        btn.addEventListener("click".() = > {
            console.log("button clicked!");
        });
    
        document.addEventListener("click".() = > {
            console.log("document clicked!");
        },true);
    </script>// What does the console output? //document clicked! //div clicked! //button clicked! // Capture and bubbleCopy the code
  • Chestnut 3

    <div class="grandfather">
        <div class="father">
            <div class="son">The text</div>
        </div>
    </div>// Add event listener fnYe/fnBa/fnEr to each divCopy the code
    • Question 1: Who was clicked on? Click on the text, calculate not click son? Click on the text, does that count as clicking dad? Click text, does it count as click grandpa? (Answer: Both.)
    • Question 2: Which fnYe/fnBa/fnEr function is called first when you click on the text? (Answer: it depends on the developer’s choice to put fnYe/fnBa/fnEr in capture or bubble.)