【 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