The words written in the front

I’ve been around the DOM event stream for a long time, but I forgot about it after I didn’t use it for a long time, so I’m going to write about it today and review some knowledge about THE DOM event stream

Classification of DOM event streams

There are two types of DOM event flow, one is captured event flow, and the other is bubbling event flow. Both are fairly easy to understand. Let’s look at them in more detail

  1. Bubble type event flow “bubble” : Yes is what your heart want, bubble is that we can common at ordinary times, such as the air bubbles in the water rises up, this is the bubble, bubble flow of events, so is that when you click on the target element, the current triggered by some event will transfer to the parent element, this is the so-called event bubbling, if you still have not understand of place, can directly see the back of the code
  2. A captured event stream is the opposite of a bubbling event stream, in that when you click on a target element, the event triggered by clicking on that target element is passed down from the parent element
  3. In fact, the DOM standard specifies that the event flow consists of three phases: the event capture phase, the target phase, and the event bubbling phase. Event capture phase: The actual target does not receive events during the capture phase. That is, during the capture phase, the event stops from Document to to. In target phase: Events occur and are processed on. But event handling is seen as part of the bubbling phase. Bubbling phase: Events propagate back to the document.

The main points of

Before we get into the details, we need to clear up a few points

  1. In the flow of events we have to remember one conclusion,Capture and then bubble
  2. Bubbling is enabled by default, so how do we enable capture? In this case, we can look up the JS Bible, addEventListener supports three parameters
1. Event: What is the current event,click,onmouseover? 2. callback: The current event callback execution by 3. Option | useCapture: If the third parameter is passed in only a Boolean, then the capture mode can be turned on. If the third parameter is passed in only a Boolean, then the capture mode can be turned on. If the third parameter is passed in only a Boolean, then the capture mode can be turned on. {capture once: Indicates whether the current callback is being implemented only once. Passive: Indicates that the listener should never call the preventDefault option.Copy the code

code

  1. The bubbling
<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
    <div>
        <p>
            <a href="void: javascript(0)"</a> </p> </div> </body> <script> $('div').click(function() {
        console.log(2)
    })
    $('p').click(function() {
        console.log(1)
    })
    $('a').click(function() {
        console.log(0)
    })
</script>
</html>
Copy the code

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
    <div>
        <p>
            <a href="void: javascript(0)">
                <span>123</span>
            </a>
        </p>
    </div>
</body>
<script>
    let div = document.getElementsByTagName('div') [0]let p = document.getElementsByTagName('p') [0]let a = document.getElementsByTagName('a') [0]let span = document.getElementsByTagName('span')[0]

    div.addEventListener("click".function() {
        console.log(2)
    })
    p.addEventListener("click".function() {
        console.log(1)
    })
    a.addEventListener("click".function() {
        console.log(0)
    }, true)
    span.addEventListener("click".function() {
        console.log(-1)
    })
</script>
</html>
Copy the code

How to stop it?

Blocking the flow of events

Event capture we can switch on and off with the third parameter of addEventListener, but how do we stop events from bubbling? Do we let events bubble? Luckily we have a stopPropagation function, which is used to prevent event bubblers (and also to prevent event capture)

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
    <div>
        <p>
            <a href="void: javascript(0)">
                <span>123</span>
            </a>
        </p>
    </div>
</body>
<script>
    let div = document.getElementsByTagName('div') [0]let p = document.getElementsByTagName('p') [0]let a = document.getElementsByTagName('a') [0]let span = document.getElementsByTagName('span')[0]

    div.addEventListener("click".function() {
        console.log(2)
    })
    p.addEventListener("click".function(e) {
        e.stopPropagation()
        console.log(1)
    })
    a.addEventListener("click".function(e) {
        console.log(0)
        // e.stopPropagation()

    })
    span.addEventListener("click".function() {
        console.log(-1)
    })
</script>
</html>
Copy the code

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
    <div>
        <p>
            <a href="void: javascript(0)">
                <span>123</span>
            </a>
        </p>
    </div>
</body>
<script>
    let div = document.getElementsByTagName('div') [0]let p = document.getElementsByTagName('p') [0]let a = document.getElementsByTagName('a') [0]let span = document.getElementsByTagName('span')[0]

    div.addEventListener("click".function() {
        console.log(2)
    })
    p.addEventListener("click".function(e) {
        e.stopPropagation()
        console.log(1)
    }, true)
    a.addEventListener("click".function(e) {
        console.log(0)
    })
    span.addEventListener("click".function() {
        console.log(-1)
    })
</script>
</html>
Copy the code

As you can see, the console prints only one, which means that this function is not only used to prevent event bubbling, it can also be used to prevent event capture, or in other words, all three phases of the event flow, which is what it does

We do have a way to stop the stream of events by using stopPropagation(), return false. This method has some defects, it only works in jQuery. In native JS the only way to prevent default behavior is to use the code first

<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>Document</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
    <div>
        <p>
            <a href="void: javascript(0)"</a> </p> </div> </body> <script> $('div').click(function() {
        console.log(2)
    })
    $('p').click(function() {
        console.log(1)
        return false$(})'a').click(function() {
        console.log(0)
    })
</script>
</html>
Copy the code

Blocking default behavior

When we said return false, we mentioned a noun that prevents default behavior. So what is default behavior? For example, when we click on the A tag, it automatically jumps to the href address. We can prevent some of the default behaviors by returning false and the other way to do that is by calling the preventDefault method, which is also designed to prevent the default event

Pay attention to the point

PreventDefault and stopPropagation are not available in IE. How do we prevent bubblings and preventDefault events in IE

// Prevent bubbling eventsfunction stopBubble(e){
    if(e &&e.TopPropagation){// Non-IE e.topPropagation (); }else{/ / Internet explorer window. Event. CancelBubble =true; }} // block default behavior // block browser default behaviorfunctionStopDefault (e){standard browserif(e && e.preventDefault){ e.preventDefault(); } // Individual IEelse{ 
        window.event.returnValue=fale;
        return false; }}Copy the code

With the above code, we can perfectly prevent bubbling and default behavior

Meaning of existence

After this long discussion of event capturing and event bubbling, we need to think about why we have event capturing and event bubbling and that’s what we’re going to talk about with event proxies,

So what is event delegate? Event delegate is the ability to manage all events of a certain type by specifying a single event handler using event bubbles (from JavaScript advanced programming).

So why can appear event delegation, when we have a li, we add the click event to li, this is no problem, but when we have hundreds of thousands of li, at this time, we will how to deal with, of course, one of the most simple way is the for loop iterates through, and then add the click event to every li, This works, but remember that the rendering speed of an HTML page is tied to the number of dom operations, and the number of DOM operations is tied to the number of events bound, and the more bound, the slower the rendering will be, so you might ask, is there a good way to do this, At this point we can use the term, event, the principle of limited event delegation is event bubbling, when we add events to li, the event flows along the li to the outer layer of the ul, so at this time we can just add on the ul and li on the same event, can realize and add the same effect on li, Let’s look at the code first

html 
<ul id="ul1"Hi > < li > < / li > < li > hello < / li > < li > hello < / li > < li > hello < / li > < li > hello < / li > < li > hello < / li > < li > hello < / li > < li > hello < / li > < / ul >Copy the code
window.onload = function(){
    var oUl = document.getElementById("ul1");
    var aLi = oUl.getElementsByTagName('li');
    for(var i=0; i<aLi.length; i++){ aLi[i].onclick =function(){ alert(123); }}}Copy the code

The above method is to add events to each li, which will definitely slow down the rendering speed. Let’s look at the code after the event broker

window.onload = function(){
    var oUl = document.getElementById("ul1");
   oUl.onclick = function(){ alert(123); }}Copy the code

Wouldn’t it be nice if we just bound an event to achieve the same effect? So this is what we call event agency

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = line, DOM event stream has been parsed, if there is any incorrect place welcome to point out, I am a program yuan in front of the road forward, and I will always go forward, I hope to be able to progress together with you welcome everyone into my Github to look at my Github