【 introduction 】

The use of events can be seen everywhere in the front-end development of various terminal environments, such as web terminal, mobile terminal H5 and small program. The visible event mechanism is the top priority of the front-end.

“Directory”

See event passing from examples

2. Event transmission

Add events

Four, cancel bubbling

5. Event delegation

Block default actions

Encapsulating events delegate custom events

[text]

See event passing from examples

Take the following plain HTML file for example

<! DOCTYPE html> <html lang="en" onclick="handleClickHtml()"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Initial =1.0"> <title>Document</title> </head> <body onclick="handleBodyClick()"> onclick="handleClick2()"> <button id="button1" onclick="handleClick1()">handleClick1</button> </div> <script> function handleClick1(e) { console.log('click1') } function handleClick2(e) { console.log('click2') } function handleBodyClick(e)  { console.log('body clicked') } function handleClickHtml(e) { console.log('html clicked') } document.addEventListener('click', e => { console.log('document clicked') }) </script> </body> </html>Copy the code

In this example, we add click events to document, HTML, body, div and button.

2. Event transmission

After the event is generated, it is passed from the Window object down to the target node and in the opposite direction when it reaches the target node

Event capture: Find listener functions from inside out

Event bubbling: Look for listener functions from outside in

The W3C, in order to keep both IE and Viewtext happy, can only stipulate that browsers should support both calls

Add events

  • Event binding API
    • IE5: x.atachevent (‘onclick’,fn)// bubbles
    • Netscape: x.arddeventListener (‘cilck’,fn)// capture
    • The W3C: X.a ddEventListener (‘ cilck, fn, Boolean)
  • If bool is not passed or falsy, let fn go and bubble
  • If BOOLTrue, let fn go capture

Four, cancel bubbling

In the following example, we can use stopPropagation to stop events from bubbling up. Click events added to window, Document, or HTML will not work

<! <div id="div1"> <button id="button1"> Button </button> </div> <script> var div1 = document.getElementById('div1') var button1 = document.getElementById('button1') div1.addEventListener('click', (e) => { console.log(e.currentTarget) }, false) button1.addEventListener('click', (e) => {console.log(e.currenttarget) e.topPropagation () Prevented the click event from bubbling up}, Function handleClickHtml(e) {console.log(' HTML clicked')} document.addEventListener('click', e => { console.log('document clicked') }) </script>Copy the code

Click button and the print result is as follows:

5. Event delegation

Consider the following scenarios for mass event listening performance:

There is a long message list to accept new messages in real time, scroll to the bottom of the load more messages, click on the message to enter the call window page, message left slide message this message

Question:

How do I add a left slip event to this message list?

In the abstract, the problem is how to efficiently add events to a large (or even unlimited) number of nodes, leaving aside vue, React and other frameworks

Cause of performance problems

Registering an event listener requires a certain amount of memory, and it is slower to handle event delivery during the capture and bubbling phase of the event as dom nodes grow

Event delegation

Events triggered by nested child nodes of the parent node will reach the parent node through event bubbling. Event handlers are not directly bound to the child node, but are monitored by the common parent node.

E.target represents the element that triggers the event. You can determine the event that responds to that element by using e.target

E.currenttarget represents the element bound to the event, pointing to the same element in the event delegate case

Adapt this example with event delegation

<! - the omitted part of the code -- -- > < div id = "div1" > < button id = "for" > button < / button > < / div > < script > document. The addEventListener (' click ', E => {// e.target: the element that triggers the event // e.currenttarget: // console.log(e.target, e.currentTarget) if (e.target.id === 'button1') { return console.log('button1 clicked') } if (e.target.id === 'div1') { return console.log('div1 clicked') } if (e.target.tagName === 'HTML') { return console.log('html clicked') } if (e.target.tagName === 'BODY') { return cosnole.log('body clicked') } }) </script>Copy the code

Clicking on HTML, div1, button1 will print the results one by one:

Prevent default events

The default event of the browser is the behavior of the browser itself, such as when we click <a href=”#”> and the browser jumps to the specified page. Also, when we scroll the mouse, the page scrolls down, but when we press the space bar and arrow keys, the page also scrolls down, and for the sake of the user experience, we need to prevent this from happening.

 function stopDefault( e ) { 
if ( e && e.preventDefault ){
     e.preventDefault(); // Block the default browser action (W3C)
 }else {
    window.event.returnValue = false; // Block the default action of the function in IE
 }
return false; 
}
Copy the code

Javascript’s return false prevents the default behavior, as long as older browsers are supported.

obj.onclick = function (){ 
  return false; 
}
Copy the code

Encapsulate event delegate

// Some code
on('click'.'#div'.'button', () = > {console.log('Button is clicked')})function on(eventType, element, selector, fn) {
    if(! (elementinstanceof Elemnet) {
        element = document.querySelector(element)
    }
    element.addEventListener(eventType, e => {
        let el = e.target
        while(! el.matches(selector)){if (element === el) {
                el = null
                break
            }
            el = el.parentNode
        }
        el && fn.call(el, e, el)
    })
    return element
}
Copy the code

Custom events