DOM event model

 <div id="grandpa">
    <div id="father">
      <div id="son">The text</div>
    </div>
  </div>
Copy the code

If you add event listener fnYe/fnBa/fnEr to each of the above divs, which event will be called first when text is clicked? Call fnYe first? Or call fnEr first?

A convention is needed to regulate the order in which events are executed.

IE5 thinks fnEr should be called first and Netscape thinks fnYe should be called first

In 2002, the W3C published the standard. The document, DOM Level 2 Events Specification, specifies that browsers should support both call orders

If there is a listener, the function will be called and the event information will be provided. If there is not, the function will be skipped

Terminology: looking for listeners from the outside in is called event capture and looking for listeners from the inside out is called event bubbling

Event binding API

.addEventListener('click',fn,bool)
Copy the code
  • If bool is not passed or false

Let fn bubble, that is, when the browser detects a listener during the bubble phase, it calls fn back with event information

  • If bool is true

Let FN go capture, that is, when the browser detects a listener during the capture phase, it calls fn back and provides the event information


--HTML--

<div id="grandpa">grandpa
    <div id="father">father
      <div id="son">son</div>
    </div>
  </div>

--Javascript--
  
let fnYe = document.getElementById('grandpa')
let fnBa = document.getElementById('father')
let fnEr = document.getElementById('son')

fnYe.addEventListener('click'.function fn() {
  console.log('grandfather')
} )
fnBa.addEventListener('click'.function fn() {
  console.log('daddy')
} )
fnEr.addEventListener('click'.function fn() {
  console.log('son')})Copy the code

The code above has no bool value and prints in order of son, father, grandfather


--HTML--

<div id="grandpa">grandpa
    <div id="father">father
      <div id="son">son</div>
    </div>
  </div>

--Javascript--
  
let fnYe = document.getElementById('grandpa')
let fnBa = document.getElementById('father')
let fnEr = document.getElementById('son')

fnYe.addEventListener('click'.function fn() {
  console.log('grandfather')},true)
fnBa.addEventListener('click'.function fn() {
  console.log('daddy')},true)
fnEr.addEventListener('click'.function fn() {
  console.log('son')},true)  
Copy the code

The above code bool is true and is printed in the order of grandfather, father and son

Event delegation

Since events propagate up to the parent element during the bubble phase, you can bind the child element’s listener function to the parent element, and let the parent element’s listener handle events of multiple child elements in a unified manner. This approach is called event delegation.

For example, we want to rent a house. If it is our own rent more trouble, need to run to the community. At this point we can entrust the intermediary to help us operate, the so-called delegation is to entrust the intermediary to help us operate the things that should be operated by ourselves.

  • The situation a

Add click events to 100 buttons

If you bind click events to every button, it will take up a lot of memory. We can listen to the ancestors of those 100 buttons and wait for them to bubble up to see if Target is one of them.


--html--

<div id="div1">
    <span>span</span>
    <button data-id = "1">click1</button>
    <button>click2</button>
    <button>click3</button>
    <button>click4</button>
    <button data-id = "5">click5</button>
    <button>click6</button>.<button>click100</button>
  </div>
  
--javascript--
  
div1.addEventListener('click'.(e) = > {
  const t = e.target
  if (t.tagName.toLowerCase() === 'button') {
    console.log('Botton is clicked')
    console.log('botton' + t.textContent + 'Clicked')
    console.log('botton' + t.dataset.id + 'Clicked')}})Copy the code
  • Scene two

Listen for click events for elements that do not currently exist

You cannot listen directly on this element because it currently does not exist. But we can use the event delegate implementation to listen for the ancestor element and wait for it to click to see if it’s the one we want.


--html--

<div id="div1"> 
  </div>
  
--javascript--
  
setTimeout(() = >{
  const button = document.createElement('button')
  button.textContent = 'click'
  div1.appendChild(button)
},1000)

div1.addEventListener('click'.(e) = > {
  const t = e.target
  if (t.tagName.toLowerCase() === 'button') {
    console.log('Botton is clicked')}})Copy the code

Advantages of event delegation

  • Save memory and improve performance.
  • You can listen for dynamic elements.