On March 17, 2020, “One question of the Day series 🚀” by Wang Ergou blog: Dig gold, think not, Zhihu, Jane book, CSDN click “like” again, form a habit, one question of the day series will be updated all the time, your support is the biggest motivation for me to continue to share 😘

To understand DOM related events, we need to understand the concept of “event flow,” which describes the order in which events are received from the page.

Event bubbling: Events are first received by the most specific element and then propagated up the hierarchy to less specific nodes or documents.

Event capture: Events are first received by less specific nodes and then propagated down to the most specific nodes. It is the opposite of event bubbling.

The event flow defined by DOM2 events consists of three phases: event capture, target, and event bubbling.

Event delegation

Event delegation, generally speaking, is to delegate the event of an element to its parent or more external elements. Its implementation mechanism is event bubbling.

Suppose you have a list and ask to click on the list item to bring up the corresponding field:

<ul id="myLink">
  <li id="1">aaa</li>
  <li id="2">bbb</li>
  <li id="3">ccc</li>
</ul>
Copy the code

Do not use event delegates

var myLink = document.getElementById('myLink');
var li = myLink.getElementsByTagName('li');

for(var i = 0; i < li.length; i++) {
  li[i].onclick = function(e) {
    var e = event || window.event;
    var target = e.target || e.srcElement;
    alert(e.target.id + ':' + e.target.innerText);  
  };
}
Copy the code

Existing problems:

  • Bind events to each list, consuming memory
  • When you have dynamically added elements, you need to re-bind events to the element

The 8K front end writes the event delegate

In fact, a lot of students have seen on the Internet that the method of event delegation is wrong, although it is wrong, but you may also pass the interview, because your interviewer may not know how to write the correct event delegation.

Let’s take a look at the error version of the event delegate:

 ul.addEventListener('click'.function(e){
     if(e.target.tagName.toLowerCase() === 'li'){
         fn() // Execute a function}})Copy the code

Event delegate written from the front end of 20K

The bug with the error version of event delegate is that if the user clicks on a SPAN in Li, fn cannot be triggered, which is obviously not true.

Let’s look at the correct event delegate:

function delegate(element, eventType, selector, fn) {
     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

The idea is to click on span, recursively traverse the ancestor elements of span to see if there is any LI in UL.

Advantages of event delegation

  • You only need to delegate the events of the same element to the parent or more external elements. You do not need to bind events to all elements, which reduces memory usage and improves performance.
  • Dynamically added elements do not need to rebind events

Points to be aware of

  • The implementation of event delegation relies on bubbling, so events that do not support event bubbling are not suitable for event delegation.
  • Not all event bindings are suitable for event delegates, and improper use can lead to events being bound to elements that do not need to be bound to events.

Tell yourself that even if you are tired, don’t forget to learn. There is no shortcut to success, only step by step. ‘!

If there is something wrong in the article, you are welcome to correct it.

Thank you ~ 💘