Advanced Programming (3rd edition) Chapter 22 Advanced Techniques
Concept of pre –
Events are the primary way in which JavaScript interacts with the browser. Events are a design pattern called the observer pattern, a technique for creating loosely-coupled code.
Objects can publish events that indicate the arrival of certain moments in the object’s life cycle. Other objects can then watch the object, wait for these moments and respond by running the corresponding code.
The observer pattern mentioned above consists of two types of objects: subjects and observers.
The principal is responsible for publishing events, and observers observe the principal by subscribing to these events
A key concept of this pattern is that the subject knows nothing about the observer, that is, it can exist alone and function normally even if the observer does not exist. On the other hand: the observer knows the subject and can register the event’s callback function (event handler).
In the case of the DOM, the DOM is the subject and your event handling code is the observer
Events are the most common way to interact with the DOM, but they can also be used in non-DOM code through custom events
The idea behind custom events is to wear an object that manages events and have other objects listen for those events.
The implementation code is as follows
EventTarget
Basic code
function EventTarget() {
this.handlers = {};
}
EventTarget.prototype = {
constructor: EventTarget,
addHandler: function (type, handler) {
if( typeof this.handlers[type] == "undefined") {this.handlers[type] = [];
}
this.handlers[type].push(handler);
},
fire: function(event) {
if(! event.targer) { event.targer =this;
}
if(this.handlers[event.type] instanceof Array) {
let handlers = this.handlers[event.type];
for (let i = 0, len = handlers.length; i < len; i++) { handlers[i](event); }}},removeHandler: function(type, handler) {
if(this.handler[type] instanceof Array) {
let handlers = this.handlers[type];
for (let i = 0, len = handlers.length; i < len; i++) {
if(handlers[i] === hander){
break; } handlers.splice(i, i); }}}}Copy the code
EventTarget
Type attributes and method interpretation
Handlers: Used to store event handlers
AddHandler (): An event handler used to register events of a given type
This method takes two parameters: the event type and the function used to handle the event. When this method is called, a check is made to see if there is already an array for that event type in the Handlers; If not, create a new one and add the handler to the end of the array using push()
Fire (): Used to fire an event
The event object is given a target property, if not already specified, and then looks for a set of handlers that correspond to the event type, calls each function, and tells the event object to customize if it has additional information
RemoveHandler (): An event handler used to unregister an event type
RemoveHandler () is an aid to addHandler(), and they take the same arguments. This method searches an array of event handlers to find the location of the handler to delete. If found, use the break operator to exit the loop, and then use the splice() method to remove the item from the array.
EventTarget
use
// Define the event handler
function handlerMessage(event) {
console.log(`Message received: ${event.message}`);
}
// Create a new object
let target = new EventTarget();
// Add an event handler
target.addHandler('message', handlerMessage);
// Trigger the event
target.fire({
type: 'message'.message: 'Hello EventTarget'
})
// Message received: Hello EventTarget
// Delete the event handler
target.removeHandler('message', handlerMessage);
// Trigger the event again
target.fire({
type: 'message'.message: 'Hello EventTarget'
})
// The event trigger does not execute the console to throw the following exception message
// Uncaught TypeError: Cannot read property 'message' of undefined
Copy the code
In the code above, the handleMessage() function is defined to handleMessage events. It takes the Event object and prints the Message property. Call the target object’s addHandler() method and pass it to the Message and handleMessage() functions. The trigger function fire() is then called and passed an object direct with two attributes, type and message. It calls the event handler for the Message event. This will output (the handleMessage() method print) to the console, then delete the event handler, and call it again without output, but the console throws an exception Uncaught TypeError: Cannot read property ‘message’ of undefined
EventTarget is encapsulated in a custom type, and other objects can inherit EventTarget and get this behavior
function inheritPrototype(subType, superType){
let prototype = Object(superType.prototype); // Create an object
prototype.constructor = subType; // Enhance objects
subType.prototype = prototype; // Specify the object
}
function Person(name, age) {
EventTarget.call(this);
this.name = name;
this.age = age;
}
inheritPrototype(Person, EventTarget);
Person.prototype.say = function (message) {
this.fire({type: 'message'.message: message});
}
Copy the code
The Person type uses the parasitic composite inheritance method to inherit EventTarget. Once the say() method is called, the event is fired, which contains the details of the message
function handlerSayMessage(event) {
console.log(`${event.targer.name} says: ${event.message}`);
}
// Create an object
var person = new Person("Allen".20);
// Add an event handler
person.addHandler("message", handlerSayMessage);
// Calls the Say method on the object, which fires the message event
person.say(" Hi There.");
// Console output: Allen says: Hi There.
Copy the code
Custom events can be useful in situations where there are multiple places in the code that interact at a given moment