Directory:
- Flow of events
- Event handler
- The event object
- Memory and Performance
History of the event:
- Events first appeared in IE3 and Netscape Navigator 2 to move some form processing from the server to the browser.
- Internet Explorer 4 and Netscape Navigator 3, both browsers offer similar but different apis that have persisted for generations.
- DOM2 standardizes DOM event apis in a logical way. All modern browsers currently implement the core of DOM2 Events.
- IE8 was the last major browser to use a proprietary event system.
I. Event Flow
The event flow describes the order in which the page receives events.
1. The IE and Netscape development teams came up with almost opposite event flow scenarios:
- IE will support event bubbling
- Netscape Communicator will support event capture streams.
- Event capture is rarely used in practice because older browsers do not support it. Event bubbling is commonly used.
2. Event Flow details:
- Event bubbling: Propagates upward from the most concrete element…
- Event capture: The least specific node receives the event first, the most specific… After..
- DOM event flow: The DOM2 Events specification specifies that event flow is divided into three phases: event capture, arrival to target, and event bubbling.
Event handlers
1. HTML event handlers
<script>
function showMessage() {
console.log("Hello world!");
}
</script>
<input type="button" value="Click Me" onclick="showMessage()"/>
Copy the code
Code executed as an event handler has access to everything in the global scope.
DOM0 event handler
The event handler assignment method started to be supported in the fourth generation of Web browsers, and is still supported by all modern browsers today, mainly because of its simplicity.
let btn = document.getElementById("myBtn");
btn.onclick = function() {
console.log(this.id); // "myBtn"
};
Copy the code
- This refers to the element itself
- This allows you to access any of the element’s attributes and methods.
- Adding event handlers in this way is registered during the bubbling phase of the event flow.
- To remove DOM0 event handlers, set the value of the event handler property to NULL:
btn.onclick = null; // Remove the event handler
Copy the code
DOM2 event handler
DOM2 Events defines two methods for assigning and removing event handlers:
- addEventListener()
- removeEventListener()
These methods take three parameters: the event name, the event handler, and a Boolean value, true for calling the event handler during the capture phase and false (the default) for calling the event handler during the bubble phase.
let btn = document.getElementById("myBtn");
btn.addEventListener("click".() = > {
console.log(this.id);
}, false);
Copy the code
The main features of DOM2 Events are:
- The main advantage of DOM2 Events is that you can add multiple event handlers to the same event
- Multiple event handlers are fired in add order
- Event handlers added via addEventListener() can only be removed using removeEventListener() and passing in the same parameters as when they were added. This means that anonymous functions added using addEventListener() cannot be removed
- In most cases, event handlers are added to the bubbling phase of the event flow, primarily for cross-browser compatibility.
let btn = document.getElementById("myBtn");
btn.addEventListener("click".() = > {
console.log(this.id);
}, false);
btn.removeEventListener("click".function() { // No effect!
console.log(this.id);
}, false);
Copy the code
4. IE event handler
IE implements a similar approach to DOM:
- attachEvent()
- detachEvent()
Both methods take the same two parameters: the name of the event handler and the event handler function.
Main features of IE Events:
-
The first argument to attachEvent() is “onclick”, DOM2 Events is “click”
-
Scope of event handlers:
(1) When DOM0 is used, the this value in the event handler is equal to the target element.
(2) When attachEvent() is used, the event handler is run in the global scope, so this equals window.
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick".function() {
console.log(this= = =window); // true
});
Copy the code
- DOM2 Events can also add multiple event handlers to an element. But event handlers fire in the reverse order in which they were added
- Anonymous functions added as event handlers cannot be removed.
5. Cross-browser event handlers
To ensure maximum compatibility with the event-handling code, simply have the code run in the bubbling phase.
var EventUtil = {
addHandler: 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; }},removeHandler: 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; }}};Copy the code
Advantages: These two methods already add and remove event handlers across browsers;
Disadvantages:
- Not addressing all cross-browser consistency issues, such as the scope of IE, the order in which multiple event handlers are executed, etc.
- Note: DOM0 only supports adding one handler to an event. Fortunately, the DOM0 browser is already rarely used, so the impact should not be significant.
3. Event object
When an event occurs in the DOM, all relevant information is collected and stored in an object named Event. Such as the element that caused the event, the type of event that occurred, and any other data that might be relevant to a particular event.
1. DOM event objects
- DOM0 or DOM2 specifies the event handler, which is passed this event object.
let btn = document.getElementById("myBtn");
btn.onclick = function(event) {
console.log(event.type); // "click"
};
btn.addEventListener("click".(event) = > {
console.log(event.type); // "click"
}, false);
Copy the code
- Inside the event handler, the this object is always equal to the value of currentTarget, and target is the actual target that fires the event.
- The preventDefault() method is used to prevent the default action for a particular event. If the cancelable attribute of the event object is true.
- The stopPropagation() method is used to immediately stop the event stream from propagating through the DOM structure, canceling subsequent event capture or bubbling.
- EventPhase represents the phase of invoking the event handler: 1 for capture, 2 for destination, and 3 for bubbling
2. IE event object
Properties/methods | type | Read and write | instructions |
---|---|---|---|
cancelBubble | Boolean value | Read/write | Default false, true to cancel bubblings (same as DOM stopPropagation()) |
returnValue | Boolean value | Read/write | Default true, false to disable event default (same as DOM preventDefault()) |
srcElement | The element | read-only | Event target (same as the DOM target property) |
type | string | read-only | The type of event that is triggered |
- If the event handler is specified using DOM0, the Event object is just a property of the Window object
var btn = document.getElementById("myBtn");
btn.onclick = function() {
let event = window.event;
console.log(event.type); // "click"
};
Copy the code
- If the event handler is specified using attachEvent(), the event object (the window object attribute) is passed to the handler as its only argument
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick".function(event) {
console.log(event.type); // "click"
});
Copy the code
-
The value of this does not always equal the event target, so it is recommended to use the srcElement attribute of the event object instead of this.
(1) When DOM0 is used, the this value in the event handler is equal to the target element.
(2) When attachEvent() is used, the event handler is run in the global scope, so this equals window.
var btn = document.getElementById("myBtn");
// DOM 0
btn.onclick = function() {
console.log(window.event.srcElement === this); // true
};
/ / IE attachEvent
btn.attachEvent("onclick".function(event) {
console.log(event.srcElement === this); // false
});
Copy the code
3. Cross-browser event objects
var EventUtil = {
getEvent: function(event) {
return event ? event : window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false; }},stopPropagation: function(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true; }},addHandler: 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; }},removeHandler: 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; }}};Copy the code
Use:
btn.onclick = function(event) {
// Get the event object
let event = EventUtil.getEvent(event);
// Get the event target
let target = EventUtil.getTarget(event);
// Cancel the default..
EventUtil.preventDefault(event);
// Cancel bubbling
EventUtil.stopPropagation(event);
};
Copy the code
4. Memory and performance
- In JavaScript, the number of event handlers on a page is directly related to the overall performance of the page. The reason:
- Each function is an object and occupies memory space. The more objects there are, the worse performance there is.
- Accessing the required DOM in the specified event handler preempts the entire page interaction.
- So if you want to optimize memory and performance issues around events, you can:
- Limit the number of event handlers on a page, because they can take up too much memory and lead to slow page response;
- With event bubbling, event delegate can solve the problem of limiting the number of event handlers.
- It is best to remove all event handlers before the page unloads.
1. Event delegation
The solution to “too many event handlers” is to use event delegates.
Event delegation takes advantage of event bubbling and allows you to manage one type of event using only one event handler. For example, add an event handler to the common ancestor node of all elements.
Event delegation has the following advantages:
- The Document object is always available, and you can add event handlers to it at any time (without waiting for a DOMContentLoaded or Load event). This means that as long as the page renders clickable elements, it works without delay.
- Save time spent setting up page event handlers. Specifying only one event handler saves both DOM references and time.
- Reduce the memory required for the entire page and improve overall performance.
2. Delete event handlers
-
Elements to be deleted will not be cleaned up properly by the garbage collector if they have event handlers on them. Therefore, it is best to manually delete the DOM’s event handler before deleting it.
-
Event handlers remain in memory if they are not cleaned up after the page is unloaded. After that, the number of residual objects in memory increases each time the browser loads and unloads the page (for example, by moving forward, backward, or refreshing). Therefore, it is best to remove all event handlers before the page is unloaded.