Event triggering
In the browser wars era, Microsoft and Netscape had a dispute over the order in which DOM events were triggered. Let’s take a look at the debate, using the click issue as an example.
HTML: <div class="grandpa"> <div class="father"> <div class="son"> let son = document.querySelector(".son") .son.addEventlistener("click",()=>{console.log(1)})Copy the code
For this code, what should be the order of notification when Son is clicked? That is, should I scan for clicked events from Grandpa to father to son, or notify clicked events from son to father to grandpa? Two different kinds of disagreement emerge.This is the schematic of it, the one from the outside in is called the capture phase, and the one from the inside out is called the bubble phase
The W3C finally combined these two orders into a method called adEventListener. According to the standard, a browser should support two ideas: first, the event should go through a capture phase, then through a bubble phase, specify three parameters in the addEventListener. The first is the name of the event to fire, the second is the function to bind to, and the third is the decision to turn capture on or off. Based on theory, let’s practice with the following code:
<div class="div2"> <button class="div3"> </div> </div> js: const grandpa = document.querySelector(".div1"); const father = document.querySelector(".div2") const son = document.querySelector(".div3") grandpa.addEventListener("click",(e)=>{ console.log(e.currentTarget); },true) father.addEventListener("click",(e)=>{ console.log(e.currentTarget); },true) son.addEventListener("click",(e)=>{ console.log(e.currentTarget); },true)Copy the code
Event capture is enabled at this point, so in the capture phase, we do grandpa, father, and son first, but if we drop true, we get
When the event is executed, the browser gives the JS object E, which contains currentTarget and Target. CurrentTarget refers to the currently monitored element, and Target refers to the element that the user operates on. Simply put, currentTarget can be target itself or a parent of Target. For example: div>span{hello}, click hello, e.target is span, e.currenttarget is div
When only one div is being listened on, the capture and bubble phases are executed in defined order, rather than capture and bubble.
The capture cannot be interrupted, but the bubbling can be cancelled. When you write e.topprogation () above e, the bubbling is interrupted and the browser does not move up again.
If you look up MDN, you can see some words about bubble, Bubbles means whether to bubble, Cancelable means whether to support developers to cancel bubble. Some special cases, such as Scroll does not support to cancel bubble, but it can use wheel and Touchstart to cancel relevant default scroll events.
Event delegation
Depending on the event bubble and e object, we wrap some sibling elements that bind to the same function with a parent element, and then bind the function that needs to bind the event to the parent element. This is a good time to do it because you only have to bind one parent class, so it’s a lot less code, and this is code that uses event delegate, you only have to bind one parent class, and it works
html:
<div class="fa">
<button class="button1">click me</button><button class="button2">click me</button><button class="button3">click me</button><button class="button4">click me</button><button class="button5">click me</button><button class="button6">click me</button>
</div>
js:
const fa = document.querySelector(".fa");
fa.addEventListener("click",(e)=>{
console.log(e.target.classList.value)
})
Copy the code
At this point, we reduced the binding of five methods because of the presence of E.target
Custom events
We can customize some events to define whether it can bubble or not
xxx.addEventListener('click', ()=>{
const event = new CustomEvent("xiaoznzk", {"detail":{name:'xiaoznz', age: 18}})
xxx.dispatchEvent(event)
})
xxx1.addEventListener('xiaoznz', (e)=>{
console.log('xiaoznz')
console.log(e)
})
Copy the code
An event called Xiaoznz is executed.