directory

  • Click on events?
  • Event capture and bubbling
  • addEventListener
  • Code diagram
  • target VS currentTarget
  • Event delegation
  • Custom events

Click events

The following leads to a question for discussion

  <div class='grandfather'>
      <div class='daddy'>
          <div class='son'>The text</div>
      </div>
  </div>
  <script>
      /* Add click events */Grandpa. AddEventListener ('click',fn); Dad. AddEventListener ('click',fn); Son. AddEventListener ('click',fn);
  </script>
Copy the code
  • Question 1: Click on who, and who? Clicked the text, calculate did not click the son, calculate did not click the father, calculate did not click the grandfather?
    • Answer: both count!

  • Question 2: Call order? Which function of fn parent, fn parent, or fn child is called first?
    • A: Either way!

Event capture and bubbling

  • In 2002, the W3C published the standard

    Document name: DOM Level 2 Events Specification

    Specifies that browsers should support both call sequences

    First, see if there are functions listening in the order “Grandpa -> Dad -> son”.

    Then see if there are any functions listening in the order “son -> Dad -> Grandpa”.

    The function is called when it is listening and provides event information. If not, skip it.

  • Event capture: Look for listener functions from outside in - capture cannot be cancelled

  • Event bubbling: Look inside out for listener functions - bubbling can be cancelled

  • The question comes: isn’t fn father fn son called twice? Not too! The developer chooses whether to place the function listener call in the capture or bubble phase.


Five, the addEventlistener

  • Event binding API

    AddEventListener (event type, callback function, Boolean)Copy the code
    1. ifNo Boolean values are propagatedOr forFalsy valueF sub n will goBubbling phase.
    2. ifThe Boolean value is trueF sub n will goCapture phase
    1. You can choose to put fn on that side.


  • Code sample
    <! DOCTYPEhtml>
    <html>
    <head>
    <meta charset="utf-8">
    <title>The bubbling demo</title>
    </head>
    <body>
     <div class="level1 x">
       <div class="level2 x">
         <div class="level3 x">
           <div class="level4 x">
             <div class="level5 x">
               <div class="level6 x">
                 <div class="level7 x">
                 </div>
               </div>
             </div>
           </div>
          </div>
        </div>
     </div>
     <script>
        /* To demonstrate the capture phase, add a third argument, true, to the addEcentListener */
    
        const level1 = document.querySelector('.level1')
        const level2 = document.querySelector('.level2')
        const level3 = document.querySelector('.level3')
        const level4 = document.querySelector('.level4')
        const level5 = document.querySelector('.level5')
        const level6 = document.querySelector('.level6')
        const level7 = document.querySelector('.level7')
    
        let n = 1
    
        level1.addEventListener('click'.(e) = >{
        const t = e.currentTarget
        setTimeout(() = >{  
            t.classList.remove('x')
        },n*1000)
        n+=1
        })
    
        level2.addEventListener('click'.(e) = >{
        const t = e.currentTarget
        setTimeout(() = >{  
            t.classList.remove('x')
        },n*1000)
        n+=1
        })
    
        level3.addEventListener('click'.(e) = >{
        const t = e.currentTarget
        setTimeout(() = >{  
            t.classList.remove('x')
        },n*1000)
        n+=1
        })
    
        level4.addEventListener('click'.(e) = >{
        const t = e.currentTarget
        setTimeout(() = >{  
            t.classList.remove('x')
        },n*1000)
        n+=1
        })
    
        level5.addEventListener('click'.(e) = >{
        const t = e.currentTarget
        setTimeout(() = >{  
            t.classList.remove('x')
        },n*1000)
        n+=1
        })
    
        level6.addEventListener('click'.(e) = >{
        const t = e.currentTarget
        setTimeout(() = >{  
            t.classList.remove('x')
        },n*1000)
        n+=1
        })
    
        level7.addEventListener('click'.(e) = >{
        const t = e.currentTarget
        setTimeout(() = >{  
            t.classList.remove('x')
        },n*1000)
        n+=1
        })
     </script>
    </body>
    </html>
    Copy the code


  • W3C event model

    1, first capture, bubbling

    2. Note that the e object is passed to all listeners

    3. After the event, the e object does not exist.

    4. Event list


Target vs. currentTarger

  • The difference between
    1. e.target— User action elements
    2. e.currentTarget— the element that the programmer listens to
    3. This is the e.c. with our fabrication: urrentTarget
  • For example,
      <div>
      	<span>The text</span>
      </div>| when users click on text, | e. arget is span | e.c. with our fabrication: urrengtTarget is divCopy the code
  • A special case

    Only one element is listened on (regardless of the parent and child being listened on at the same time). Fn listens for click events in the capture and bubble phases, respectively, and the element clicked by the user is the one the developer listens for

    <div>This is the div being listened on</div>
    
    <script>
        let div=document.querySelector('div');
        div.addEventListener('click'.() = >{
            console.log(1);
        })	// Bubble phase
    
        div.addEventListener('click'.() = >{
            console.log(2);
        },true)	// Capture phase
    </script>
    Copy the code
  • Output 1, 2, or 2, 1? Correct answer: Who listens first who executes first.

7. Event delegation

  • The situation a

    You want to listen for 100 buttons, what do you do?

  • Scene two

    You want to listen for events of elements that do not currently exist. What do you do?

  • Correct solution: Listen for the ancestor of these elements and wait for the bubble or event to determine if it is the element I want to listen on.
  • Code sample
    
            
    <html>
    <head>
        <meta charset='UTF-8'>
        <title>Event delegation</title>
    <head>
    <body>
        <div class='max'>
            <button class='btn-1'>btn1</button>
            <button class='btn-2'>btn2</button>
            <button class='btn-3'>btn3</button>(omitted 96 buttons).<button class='btn-100'>btn100</button>
        </div>
        <script>
             /* Listen for the ancestor element */
             let btn_max=document.querySelector('.max');
             btn_max.addEventListener('click'.() = >{
                 const t = e.target;	// To save the e.target object, since it is an asynchronous result, the e.target object will disappear when clicked.
                 if(e.tagName.toLowerCase()==='button') {console.log('Button is clicked');
                     console.log('The button clicked is'+ t.className);	// This will tell you which button was clicked}})</script>
    </body>
    <html>
    Copy the code

Custom events

  <! DOCTYPEhtml>
  <html>
  <head>
  <meta charset="utf-8">
  <title>JS Bin</title>
  </head>
  <body>
      <div id=div1>
          <button id=button1>Click trigger the Frank event</button>
      </div>
      <script>
          button1.addEventListener('click'.() = >{
              const event = new CustomEvent("frank", {"detail": {name:'frank'.age: 18}})
              button1.dispatchEvent(event)
          })

          button1.addEventListener('frank'.(e) = >{
              console.log('frank')
              console.log(e)
          })
      </script>
  </body>
  </html>
Copy the code

This code creates a custom event, more on that.