Make writing a habit together! This is my first day to participate in the “Gold Digging Day New Plan · April More text challenge”, click to see the details of the activity.

Introduction to the

Recently in the interview, I found that many partners are not familiar with JS events, such as the way of binding events, event monitoring, event delegation, event propagation, event capture, event bubbling and so on. Today, THE author summarizes, I hope to help you.

What are the ways to bind events to DOM elements

There are three main ways to bind events to the DOM:

  1. indomDirectly bound on the element
  2. injsTo derivedomThe element is then bound
  3. Use event listening. The advantage of using event listening is that you can give the samedomObject to bind multiple identical events.

Here are three examples of three ways to bind events

Bind directly on dom elements

It is common to bind directly to DOM elements, writing the corresponding events and handling methods directly in the HTML tag.

<div id="div1" onclick="click1(event)">
  <span>Point me 1</span>
</div>
Copy the code
// Bind events directly to dom elements
function click1(e) {
  console.log(this); // window
  console.log("currentTarget", e.currentTarget);  
       
console.log("target", e.target); // } // const click1 = (e) => { // console.log(this); // window // console.log("currentTarget", e.currentTarget);
// console.log("target", e.target); // // }; Copy the code

Get the DOM element in JS and bind it

<div id="div2">
  <span>Me for 2</span>
</div>
Copy the code
// Get the DOM element in js for event binding
const div2 = document.getElementById("div2");
div2.onclick = function (e) {
  console.log(this);  
       
console.log("currentTarget", e.currentTarget);
console.log("target", e.target); }; // div2.onclick = (e) => { // console.log(this); // window // console.log("currentTarget", e.currentTarget);
// console.log("target", e.target); // }; Copy the code

Using Event Listening

There are two versions of event listener: standard event listener and non-standard event listener. Generally, we need to do compatibility processing when writing code. This author will summarize later.

// Standard event listening is supported only by IE9 and above
// Add the event Element. addEventListener(event, function, EventListenerOptions)
/ / remove event element. The removeEventListener (event, function)

eventEvent name, which supports all DOM events. Use listeners without the event prefix on.functionSpecifies the function to be executed when the event is triggered. EventListenerOptions {// Usually we set a Boolean value to capture, bubble or capture.capture? : boolean// (Optional) Specifies whether the event is executed in the capture or bubble phase. True, capture. False, bubble. False by default.once? : boolean// Indicates that the listener is invoked at most once after being added. If true, the listener is automatically removed after it is called.passive? : boolean// When set to true, the listener never calls preventDefault(). If the listener still calls this function, the client ignores it and throws a console warning.
}
    
// Non-standard IE8 and below use this
Element. attachEvent("on" + event, function)
// Remove element.detachEvent("on" + event, function)Event :(required) event type. Add "on", for example, onclick.functionSpecifies the function to be executed when the event is triggered.Copy the code

The following examples are written using standard version event listeners.

<div id="div3">
  <span>Point me 3</span>
</div>
Copy the code
// Add events to dom elements using event listeners, and you can add more than one of the same events
const div3 = document.getElementById("div3");
div3.addEventListener("click".function (e) {
  console.log(this);  
       
console.log("currentTarget", e.currentTarget);
console.log("target", e.target); // }); div3.addEventListener("click".(e) = > { console.log(this); // window console.log("currentTarget", e.currentTarget);
console.log("target", e.target); }); Copy the code

What is the difference between target and currentTarget in event objects

From the example above we can see that target is the element that triggers the event and currentTarget is the element that binds the event.

What is event propagation and what are the three stages of event propagation?

When an event occurs on a DOM element, it does not occur exclusively on that element. Instead, events are transmitted, and the transmission process is called event propagation.

Event propagation can be divided into capture stage, target stage and bubble stage

  • The capture phase event starts at the window and moves down to each element until the target element is reached.
  • The target phase event has reached the target element.
  • Bubbling phase events bubble up from the target element and then up to each element until they reach the window.

The event propagation path is shown in figure 1

Event bubbling and event capture

Dubbed bubbling: When a mouse click or a DOM event is triggered, the browser propagated the event from within the root node.

Event capturing: When a mouse click or a DOM event is triggered (the element that triggered the DOM event is called the event source), the browser propagates the event from the root node => event source (from outside to inside).

The DOM standard event stream is triggered in the order of capture and then bubble. That is, when dom events are triggered, event capture is carried out first, and event bubbling is carried out through event propagation after event source is captured. But the default is bubbling, so the event is triggered when bubbling, that is, from inside out.

Change the event trigger time

From the above we know that events go through the capture to bubble phase, but the default event firing time is during the bubble phase. So is there any way we can change the event trigger time? For example, you want to fire events during the capture phase.

This is ok, we can use the event listener, set the third parameter of the addEventListener method to true to change the event to capture phase execution. In Vue we use @click.capture to turn events into capture phase execution.

Prevents events from bubbling

We use e.topPropagation () or e.cuancelbubble = true; Prevents events from bubbling.

In Vue we use @click.stop to prevent events from bubbling.

Prevents event default behavior

We use e.preventDefault() or e.returnValue = true; (old IE) prevents event default behavior.

In Vue we use @click.prevent to prevent event default behavior.

Event delegation

Event delegation is the use of bubbling principle, the event is added to the parent element or ancestor element, triggering the execution effect. Reasonable use of event delegate can greatly improve program performance.

For example, if we want to pop up the contents of each LI tag when we click on it, we can use the event delegate. By binding events to the parent ul element, there is no need to bind events to each li element.

<ul onclick="click4(event)">
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>
Copy the code
const click4 = (e) = > {
  const event = e || window.event;
  const target = event.target || event.srcElement;
  alert(target.innerText);
};
Copy the code

Event delegate can significantly improve event processing speed and reduce memory usage. With event delegate, we can reduce memory consumption by not binding a listener event to each child element. In addition, we can also achieve dynamic binding of events by using the event broker. For example, when a new child node is added, we do not need to add a listening event to it. The events occurring in it will be handled by the listener function in the parent element.

Generic event listener functions

As we know from the previous introduction, there are standard and non-standard events, so there will be a little difference in writing. Such as event listening methods, prevent event bubbling methods, prevent default event methods, get event object methods, and so on. Therefore, a general compatibility scheme is needed to ensure the availability of methods.

const EventUtils = {
  // Add events
  addEvent: function(element, type, handler) {
    if (element.addEventListener) {
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
      element.attachEvent("on" + type, handler);
    } else {
      element["on"+ type] = handler; }},// Remove the event
  removeEvent: function(element, type, handler) {
    if (element.removeEventListener) {
      element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
      element.detachEvent("on" + type, handler);
    } else {
      element["on" + type] = null; }},// Get the event target
  getTarget: function(event) {
    return event.target || event.srcElement;
  },

  // Get a reference to the event object, get all the information about the event, and ensure that the event is always available
  getEvent: function(event) {
    return event || window.event;
  },

  // Prevent events (mainly event bubbling, since IE does not support event capture)
  stopPropagation: function(event) {
    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true; }},// Cancel the default behavior of the event
  preventDefault: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
    } else {
      event.returnValue = false; }}};Copy the code

Custom events

In addition to using system-built events, JS also allows you to create custom events.

We can use the new Event () or new CustomEvent () to create an Event, use the document. The addEventListener to listen for an Event, Use document.dispatchEvent or Document. fireEvent to fire the event.

// Creating custom events cannot pass parameters
const myEvent = new Event("test");

// Listen for custom events
document.addEventListener("test".function (e) {
  console.log("Custom event triggered", e);
});

// Triggers a custom event
setTimeout(function () {
  if (document.dispatchEvent) {
    document.dispatchEvent(myEvent);
  } else {
    // Compatible with older browsers
    document.fireEvent(myEvent); }},2000);

Copy the code

When you create a CustomEvent using new CustomEvent(), you can pass parameters (the parameter is an object, the key must be the detail value is the parameter we need to pass) that can be retrieved from the detail of the event object.

// Create a custom event that can pass parameters. You must use detail as the key otherwise you cannot get it
const myEvent2 = new CustomEvent("test2", { detail: { name: "randy"}});// Listen for custom events
document.addEventListener("test2".function (e) {
  console.log("Custom event triggered parameter is", e.detail); // {name: 'randy'}
});

// Triggers a custom event
setTimeout(function () {
  if (document.dispatchEvent) {
    document.dispatchEvent(myEvent2);
  } else {
    // Compatible with older browsers
    document.fireEvent(myEvent2); }},3000);
Copy the code

extension

stopImmediatePropagation()

The stopImmediatePropagation() method prevents the rest of the event handlers from being executed. If three events are bound to an element and this method is called on one of them, the other two events will not be executed.

Load event and DOMContentLoaded event

When the onLoad event is triggered, all the DOM, stylesheets, scripts, images, and Flash on the page have been loaded.

When the DOMContentLoaded event is triggered, only when the DOM is loaded, excluding style sheets, images, and Flash. If both CSS and JS exist on the page, and js exists behind the CSS, the DOMContentLoaded event is executed after the CSS is loaded. In other cases, DOMContentLoaded does not wait for CSS to load, and the DOMContentLoaded event does not wait for images, videos, and other resources to load.

Afterword.

Thank you for your patience, this article is the author’s personal learning notes, if there are fallacies, please inform, thank you! If this article is of any help to you, please click on the “like” button. Your support is my motivation to keep updating!