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

EventTargetBasic 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

EventTargetType 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.

EventTargetuse

// 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