The browser’s event model

The so-called browser event model refers to the listener function to respond to events. After the event occurs, the browser listens for the occurrence of the event and executes the corresponding listener function

1. Listen to the function Settings

There are three ways to set up listener functions:

  1. HTML on-events

    The listener function is set in HTML with the event listener attribute ‘on-‘ + event name

    Once the event is triggered, the value of the on-event name attribute is passed into the javascript engine for execution

    Disadvantages: Violates the separation of HTML and JavaScript

    <div onclick="func()"></div>
    <! Set the click event property for the div -->
    <! Func () is passed into the javascript engine to execute when the click event is triggered.
    Copy the code
  2. The event attribute of the element node

    You can set listener functions for object properties of element nodes

    Disadvantages: Only one listener can be set for an event. If more than one listener is set, the last listener will prevail

    div.onclick = fn
    div.onclick = func
    Copy the code

    When the div event is triggered, the func function is executed

  3. EventTarget.addEventListener()

    You can set listeners for any event on a node by setting the addEventListener function for it

    div.addEventListener('click'.() = > console.log(1), false)
    div.addEventListener('click'.() = > console.log(2), false)
    Copy the code

    Listen for the click event for the div element, and when the click event is triggered, the function is executed in the bubble phase, printing 1 and 2

If the listener is not an ES6 function, its this is the node element corresponding to the event

2. Dissemination of events

When an event is triggered, if its ancestor also listens for the same event, its ancestor also triggers the corresponding listener function of the event

The spread of events is divided into three stages:

  1. From the Window object to the target node, called the “capture phase”
  2. Triggered at the target node, called the “target phase”
  3. From the target node to the Window object, called the “bubbling phase”
<div id=d1>
  <div id="d2">
    <div id="d3"></div>
  </div>
</div>
Copy the code
d1.addEventListener('click', ()=>console.log(1), true)
d2.addEventListener('click', ()=>console.log(2), true)
d3.addEventListener('click', ()=>console.log(3), true)
d1.addEventListener('click', ()=>console.log(11), false)
d2.addEventListener('click', ()=>console.log(22), false)
d3.addEventListener('click', ()=>console.log(33), false)
Copy the code
  • When you click on the D3 element, the console prints 1, 2, 3, 33, 22, 11
  • Among them, 1, 2 are output from the capture stage, 3, 33 are output from the target stage, 22, 11 are output from the bubble stage

Note: If the event is triggered only on the target node, the execution of the listener function is not affected by whether it is captured or bubbled. The execution of the function is determined by the sequence of the setting function

2.1 stopPropagation()preventDefault()

stopPropagation()Prevents bubbling without blocking default events

preventDefault()Prevents default events without preventing bubbling

A default event is the browser’s default behavior when an event is triggered, such as

  • Clicking on a link takes you to the page corresponding to the URL
  • Type characters in the text box and the characters are entered into the text box
  • Press the left mouse button on the text and move it to select the text
inner.addEventListener('contextmenu'.(e) = > {
    console.log("event1")
    e.preventDefault()
})
mid.addEventListener('contextmenu'.(e) = > {
    console.log("event2")
    e.stopPropagation()
})
container.addEventListener('contextmenu'.(e) = > {
    console.log("evnet3")})Copy the code
  • Right clicking on inner does not bring up the menu bar, but outputs event1 and event2, but does not output event3, preventing the default event from firing on inner rather than preventing the event from bubbling
  • If you right-click on mid to bring up the menu bar, evnet2 is printed, but event3 is not printed, indicating that the event on mid is prevented from continuing to bubble up, rather than preventing the default event from being triggered

2.2 targetcurrentTarget

Target represents the element that triggers the event, and currentTarget refers to the element being listened on

<div id="container">
  <div id="inner"></div>
</div>
Copy the code
container.addEventListener("click".function(e) {
  console.log(this)
  console.log(e.target)
  console.log(e.currentTarget)
})
Copy the code

In the example above, clicking on the inner element will output container, inner, container. E.currenttarget is the element that is listening for the corresponding event, and e.turget is the element that triggers the event

3. Agency of events

When it is necessary to set the same listener function for a large number of nodes, the listener function can be set on the ancestor node. Whenever an event is triggered by the descendant node of the ancestor node, the listener function of the ancestor node will process the event triggered by the descendant node. This not only saves memory for setting up listeners for a large number of descendant nodes, but also works with dynamically generated nodes

// When a child of an Element matched by the selector selector is clicked, pass the event to the callback function and execute function on(eventType: string, element: object, selector: string, callback: object) { element.addEventListener(eventType, If (t.matches(selector)) {callback.call(t, e)}})}Copy the code
When an event is triggered by a descendant of the child selector, Function on(eventType, Element, selector, callback) {element.addEventListener(eventType, selector, callback); e => { let t = e.target while (! If (t === element) return else t = t.parentNode} callback.call(t, t, t, t, t, t, t) e) }) }Copy the code