Javascript capture phase and bubbling phase (DOM2 level events, firefox, chrome, ie9, safari)

The events specified in the DOM2-level event flow include three stages: the event capture stage, the in-target stage and the event bubbling stage.

The first thing that happens is event capture. Then the actual target receives the event. The last stage is the bubbling stage.

The first parameter of addEventListener is the event name without the on prefix, the second parameter is the bound function, this function has the only parameter event, the third parameter is isCapture, whether to capture the meaning of phase execution. When set to false, it is executed in the bubbling phase, which is our usual way. Because we can execute event.stopPropagation() in the event function bound to the inner DIV to prevent the event from continuing to pass.

Give a piece of JS sample code:

<!DOCTYPE html>
<html>
<head>
    <title>js test</title>
</head>
<body>
<div id="outer">
    Outer DIV
    <div id="inner">内层DIV</div>
</div>
<script>
    var outer = document.getElementById('outer');
    var inner = document.getElementById('inner');

    /**
     * addEventListener binds events to Dom elements
     * Parameter 1: Event name (does not start with on)
     * Parameter 2: The function executed by the event
     * Parameter 3: Whether to execute according to the capture stage, generally set to false, and execute in the bubbling stage
     * illustrate:
     * The event flow specified by DOM2-level events consists of three stages.
     * The first stage is the event capture stage, which is passed from outside to inside;
     * The second stage is in the target stage. In this stage, the parameter 3 is set to false or true, and it is executed in the order of binding.
     * The third stage is the bubbling stage, which is passed from the inside out.
     * Notice:
     * Comments below are for a single click on "Inner DIV"
     */
    outer.addEventListener('click', function(event){
        console.log('outer clicked! false 1'); // Executed last, because it is in the outermost bubbling phase, but first if the "outer DIV" is clicked
    }, false);
    outer.addEventListener('click', function(event){
        console.log('outer clicked! true 2'); // Executed first because it is in the outer capture phase, but if the "outer DIV" is clicked, the second execution
    }, true);

    
    inner.addEventListener('click', function(event){
        console.log('inner clicked! false 1'); // 2nd execution, because it is the target
    }, false);
    inner.addEventListener('click', function(event){
        console.log('inner clicked! true 2'); // 3rd execution, because it is the target
    }, true);
    inner.addEventListener('click', function(event){
        console.log('inner clicked! false 3'); // 4th execution, because it is the target
    }, false);
</script>
</body>
</html>

 In the above code, open the console, if you click the "inner DIV" text, you will get the following execution results:


The third parameter of the addEventListener function is set to false, which is the most commonly used. The bound function will be executed in the bubbling phase. If it is set to true, it will be executed in the capture phase. However, if the DOM element is the target element when the event occurs, then the bound function will be executed. The fixed function is executed in the target stage. At this time, setting true or false is meaningless, and the function will be executed in the order of binding.

It can be seen here that the event binding function of the outermost DIV in the capture phase is executed first.

Then there is the event function bound by the target DIV in order (it has nothing to do with whether the third parameter is false or true).

The last is the bubbling phase binding function of the outermost DIV.

 

If you click on the "outer DIV", you get the following result:



 This is the execution order is based on the binding order, because at this time the two functions are no longer aimed at the bubbling phase or the capturing phase, but are executed in the target phase.

 

The event delivery order is: window -- document -- html -- body -- div ...

We add a window binding event to the code, and we will see that the window is the outermost layer, the capture phase is executed first, and the bubbling phase is executed last.

<!DOCTYPE html>
<html>
<head>
    <title>js test</title>
</head>
<body>
<div id="outer">
    Outer DIV
    <div id="inner">内层DIV</div>
</div>
<script>
    var outer = document.getElementById('outer');
    var inner = document.getElementById('inner');

    /**
     * addEventListener binds events to Dom elements
     * Parameter 1: Event name (does not start with on)
     * Parameter 2: The function executed by the event
     * Parameter 3: Whether to execute according to the capture stage, generally set to false, and execute in the bubbling stage
     * illustrate:
     * The event flow specified by DOM2-level events consists of three stages.
     * The first stage is the event capture stage, which is passed from outside to inside;
     * The second stage is in the target stage. In this stage, the parameter 3 is set to false or true, and it is executed in the order of binding.
     * The third stage is the bubbling stage, which is passed from the inside out.
     * Notice:
     * Comments below are for a single click on "Inner DIV"
     */
    outer.addEventListener('click', function(event){
        console.log('outer clicked! false 1'); // Executed last, because it is in the outermost bubbling phase, but first if the "outer DIV" is clicked
    }, false);
    outer.addEventListener('click', function(event){
        console.log('outer clicked! true 2'); // Executed first because it is in the outer capture phase, but if the "outer DIV" is clicked, the second execution
    }, true);

    
    inner.addEventListener('click', function(event){
        console.log('inner clicked! false 1'); // 2nd execution, because it is the target
    }, false);
    inner.addEventListener('click', function(event){
        console.log('inner clicked! true 2'); // 3rd execution, because it is the target
    }, true);
    inner.addEventListener('click', function(event){
        console.log('inner clicked! false 3'); // 4th execution, because it is the target
    }, false);
    
    window.addEventListener('click', function(event){
        console.log('window clicked! false');
    }, false);
    window.addEventListener('click', function(event){
        console.log('window clicked! true');
    }, true);
</script>
</body>
</html>

 Click "Inner DIV", you can get the following results:



 

If we add event.stopPropagation() in the event binding function of the capture phase of the window; then the event is killed in this phase. code show as below:

<!DOCTYPE html>
<html>
<head>
    <title>js test</title>
</head>
<body>
<div id="outer">
    Outer DIV
    <div id="inner">内层DIV</div>
</div>
<script>
    var outer = document.getElementById('outer');
    var inner = document.getElementById('inner');

    /**
     * addEventListener binds events to Dom elements
     * Parameter 1: Event name (does not start with on)
     * Parameter 2: The function executed by the event
     * Parameter 3: Whether to execute according to the capture stage, generally set to false, and execute in the bubbling stage
     * illustrate:
     * The event flow specified by DOM2-level events consists of three stages.
     * The first stage is the event capture stage, which is passed from outside to inside;
     * The second stage is in the target stage. In this stage, the parameter 3 is set to false or true, and it is executed in the order of binding.
     * The third stage is the bubbling stage, which is passed from the inside out.
     * Notice:
     * Comments below are for a single click on "Inner DIV"
     */
    outer.addEventListener('click', function(event){
        console.log('outer clicked! false 1'); // Executed last, because it is in the outermost bubbling phase, but first if the "outer DIV" is clicked
    }, false);
    outer.addEventListener('click', function(event){
        console.log('outer clicked! true 2'); // Executed first because it is in the outer capture phase, but if the "outer DIV" is clicked, the second execution
    }, true);

    
    inner.addEventListener('click', function(event){
        console.log('inner clicked! false 1'); // 2nd execution, because it is the target
    }, false);
    inner.addEventListener('click', function(event){
        console.log('inner clicked! true 2'); // 3rd execution, because it is the target
    }, true);
    inner.addEventListener('click', function(event){
        console.log('inner clicked! false 3'); // 4th execution, because it is the target
    }, false);
    
    window.addEventListener('click', function(event){
        console.log('window clicked! false');
    }, false);
    window.addEventListener('click', function(event){
        event.stopPropagation();
        console.log('window clicked! true');
    }, true);
</script>
</body>
</html>

 The execution result is as follows:


 

Note: addEventListener is invalid in IE8, only attachEvent can be used in IE8 , when attachEvent function is bound to event function, only two parameters are supported, these two parameters are the same as the first two parameters of addEventListener, the first is the event name, but The event name has one more prefix than addEventListener, and the second is the event binding function, which takes the only parameter event. However, because the event functions bound by attachEvent do not have a third parameter, they are all executed in the bubbling phase, and the default order is exactly the opposite of that of addEventListener, which is bound first and then executed, and the last bound is executed first.

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327045796&siteId=291194637