This is the fourth day of my participation in the August More text Challenge. For details, see:August is more challenging

EventTarget interface

EventTargetAn overview of the interface

DOM event operations (listening and firing) are defined in the EventTarget interface. This interface is deployed on all node objects, as well as other browser-built objects that require event communication (for example, XMLHttpRequest, AudioNode, AudioContext).

The interface mainly provides three instance methods.

  • addEventListener: Binds an event listener function
  • removeEventListener: Removes the event listener function
  • dispatchEvent: Triggers events

EventTarget.addEventListener()

EventTarget. AddEventListener () used in the current node or objects, define a specific event monitoring function. Once this event occurs, the listening function is executed. This method does not return a value.

target.addEventListener(type, listener[, useCapture]);
Copy the code

This method takes three arguments.

  • type: Event name, case sensitive.
  • listener: Listening function. The listener function is called when an event occurs.
  • useCapture: A Boolean value indicating whether the listening function is triggered during capture. Default isfalseThe listener is only fired during the bubble phase. This parameter is optional.

Here’s an example.

function hello() {
  console.log('Hello world');
}

var button = document.getElementById('btn');
button.addEventListener('click', hello, false);
Copy the code

In the above code, the addEventListener method of the Button node is bound to hello, the listener for the click event, which is triggered only during the bubble phase.

In the code above, the second argument to the addEventListener method is an object with a handleEvent method.

Second, the third parameter can be a property configuration object in addition to the Boolean value useCapture. This object has the following properties.

  • capture: A Boolean value indicating whether the event is inCapture phaseTriggers the listening function.
  • once: A Boolean value indicating whether the listener is fired only once and then removed automatically.
  • passive: A Boolean value indicating that the listening function does not call the eventpreventDefaultMethods. If the listening function is called, the browser will ignore the request and print a warning on the monitor console.

If you want the event listener function to be executed only once, you can turn on the once property of the property configuration object.

Element.addeventlistener ('click', function (event) {// Execute code only once and this points to element Console.log (this.nodename); // "element" }, {once: true});Copy the code

The addEventListener method can add multiple different listener functions for the same event on the current object. These functions fire in the order they are added, that is, added first, fired first. If you add the same listener multiple times for the same event, the listener will only be executed once and any additional additions will be removed automatically (you don’t have to manually remove them using the removeEventListener method).

In the above code, this inside the listening function points to the element object where the event is located.

EventTarget.removeEventListener()

EventTarget. RemoveEventListener method is used to remove the addEventListener method to add events to monitor function. This method does not return a value.

div.addEventListener('click', listener, false);
div.removeEventListener('click', listener, false);
Copy the code

Parameter to the removeEventListener method, exactly the same as the addEventListener method. Its first parameter, “event type,” is case sensitive.

Note that the listener removed by the removeEventListener method must be the same listener added by the addEventListener method and must be on the same element node, otherwise it is invalid.

EventTarget.dispatchEvent()

EventTarget. DispatchEvent method triggers the specified event on the current node, which triggers the implementation of monitoring function. This method returns a Boolean value as long as one of the listeners calls event.preventDefault (), and true otherwise.

target.dispatchEvent(event)
Copy the code

The argument to the dispatchEvent method is an instance of an Event object.

para.addEventListener('click', hello, false);
var event = new Event('click');
para.dispatchEvent(event);
Copy the code

The above code fires the click event on the current node.

If the argument to the dispatchEvent method is empty, or is not a valid event object, an error will be reported.

The event model

Monitoring function

The event model of the browser is to react to events through listener functions. After the event occurs, the browser listens to the event and executes the corresponding listening function. This is the main programming approach of the Event-driven programming model.

JavaScript has three ways to bind listening functions for events.

The on-attribute of HTML

The HTML language allows you to define the listening code for certain events directly in the attributes of an element.

<body onload="doSomething()">
<div onclick="Console. log(' Trigger event ')">
Copy the code

The above code specifies the listening code for the load event on the body node and the click event on the div node. Once the event occurs, this code is executed.

The event listener attribute of the element is on plus the event name. For example, onLOAD is on + LOAD, which means the listening code for the load event.

Note that the values of these properties are the code to be executed, not a function.

<! - right - >
<body onload="doSomething()">
Copy the code

Once the specified event occurs, the value of the on-property is passed in as-is to the JavaScript engine for execution. So if you want to execute a function, don’t forget to add parentheses. Using this method will only trigger during the bubble phase.

Setting the on-attribute directly has the same effect as setting the on-attribute through the element node’s setAttribute method.

el.setAttribute('onclick'.'doSomething()');
/ / is equivalent to
// <Element onclick="doSomething()">
Copy the code

Event attributes of the element node

The event attribute of the element node object can also specify the listening function.

window.onload = doSomething;

div.onclick = function (event) {
  console.log('Trigger event');
};
Copy the code

The listener function specified using this method will also only fire during the bubble phase.

Note that this method differs from HTML’s on-attribute in that its value is the function name (doSomething), unlike the latter, where the full listener code (doSomething()) must be given.

EventTarget.addEventListener()

All DOM node instances have the addEventListener method, which defines the listener function for events for that node.

window.addEventListener('load', doSomething, false);
Copy the code

For a detailed description of the addEventListener method, see the EventTarget interface above.

summary

Of the three methods above, the first “HTML on-attribute” violates the principle of separating HTML from JavaScript code. Writing the two together is not good for code division, so it is not recommended.

The disadvantage of the second “event attribute of an element node” is that only one listener can be defined for the same event, that is, if the onclick attribute is defined twice, the latter definition overwrites the previous one. Therefore, it is not recommended.

The third EventTarget. AddEventListener is recommended to specify surveillance function method. It has the following advantages:

  • Multiple listener functions can be added to the same event.
  • You can specify in which phase (capture or bubble) the listening function is triggered.
  • In addition to DOM nodes, other objects (such aswindow,XMLHttpRequestEtc.), which is equivalent to the entire JavaScript unified listening function interface.

This point

The this inside the listening function points to the element node that fired the event. This is the same for all three of the listening functions.

// The HTML code is as follows
  // BTN
var btn = document.getElementById('btn');

/ / write two
btn.onclick = function () {
  console.log(this.id); // btn
};

/ / writing three
btn.addEventListener(
  'click'.function (e) {
    console.log(this.id); // btn
  },
  false
);
Copy the code

The above two ways of writing, click the button after the output of BTN.

Propagation of events

To each child element and its parent element are propagation. There are three stages of transmission.

  • The first stageFrom:windowThe conduction of the object to the target node (from the upper layer to the lower layer) is called the Capture phase.
  • The second phase: triggered on the target node, known as the “target phase”.
  • The third stage: is transmitted back from the target nodewindowObjects (passed back from the bottom to the top), called the bubbling phase.

This three-stage propagation model allows the same event to be fired on multiple nodes.

<div> <p> Click </p> </div>Copy the code

In the above code, there is a

node within the

node.

If you set a listener for the click event for both nodes (one listener for each node’s capture phase and one listener for each node’s bubble phase), you set a total of four listener functions. Then, for a click on

, the click event is triggered four times.

var phases = { 1: 'capture', 2: 'target', 3: 'bubble' }; var div = document.querySelector('div'); var p = document.querySelector('p'); div.addEventListener('click', callback, true); p.addEventListener('click', callback, true); div.addEventListener('click', callback, false); p.addEventListener('click', callback, false); function callback(event) { var tag = event.currentTarget.tagName; var phase = phases[event.eventPhase]; console.log("Tag: '" + tag + "'. EventPhase: '" + phase + "'"); EventPhase: 'capture' // Tag: 'P'. EventPhase: 'target' // Tag: 'P'. EventPhase: 'target' // Tag: 'P'. 'target' // Tag: 'DIV'. EventPhase: 'bubble'Copy the code

The above code indicates that the click event is triggered four times: once each for the capture and bubble phases of the

node, and twice for the target phase of the

node.

  1. Capture phase: Event from<div>to<p>When propagated, trigger<div>theclickEvents;
  2. Target phase: Event from<div>arrive<p>When the trigger<p>theclickEvents;
  3. Bubbling phase: Events from<p>Back to the<div>Is triggered again<div>theclickEvents.

The

node has two listener functions (the difference in the third argument of the addEventListener method causes two listener functions to be bound), so both are fired once by the click event. So,

will have two outputs in the target phase.

The uppermost object for event propagation is window, followed by Document, HTML (document.documentElement), and body (document.body). In other words, in the above example, the event propagation sequence is window, document, HTML, body, div, p in the capture phase, and P, div, body, HTML, document, window in the bubble phase.

Proxy for events

Since events will propagate upward to the parent node in the bubble phase, the listening function of the child node can be defined on the parent node, and the listening function of the parent node can handle the events of multiple child elements in a unified manner. This method is called delegating events.

var ul = document.querySelector('ul');

ul.addEventListener('click'.function (event) {
  if (event.target.tagName.toLowerCase() === 'li') {
    // some code}});Copy the code

In the above code, the listener for the click event is defined on the

    node, but it actually handles the click event on the child node

  • . The advantage of this is that you can handle events for multiple child nodes by defining a single listener function instead of defining a listener function on each
  • node. And when you add a child node later, the listening function still works.

If you want an event to stop propagating until it reaches a node, you can use the stopPropagation method of the event object.

// After the event propagates to the p element, it no longer propagates downward
p.addEventListener('click'.function (event) {
  event.stopPropagation();
}, true);

// After the event bubbles to the p element, it no longer bubbles upwards
p.addEventListener('click'.function (event) {
  event.stopPropagation();
}, false);
Copy the code

In the above code, stopPropagation prevents the propagation of events in the capture and bubble phases, respectively.

However, the stopPropagation method only prevents the propagation of the event and does not prevent the event from triggering the listener for other click events on the

node. That is, not to cancel the click event completely.

If you want to cancel the event completely and not trigger all subsequent click listeners, you can use the stopImmediatePropagation method.

p.addEventListener('click'.function (event) {
  event.stopImmediatePropagation();
  console.log(1);
});

p.addEventListener('click'.function(event) {
  // Will not be triggered
  console.log(2);
});
Copy the code

In the code above, the stopImmediatePropagation method can cancel the event completely, so that all subsequent click listeners are no longer triggered. So, it’s only going to print 1, it’s not going to print 2.