Starting from today’s chapter, I will focus on the event management of KitJs, and try to use simple language to reveal to you how the mainstream js framework implements its own independent event management function internally.
(1) Ordinary Dom events
We can generally write events in HTML through support
Or get the dom object and bind it
document.getElementById(‘a’).onclick=function(){alert(1)}
or secondary event
document.getElementById(‘a’).addEventListener(‘click’,function(){alert(1)},flase)
or via script tag
The W3C standard recommends the third binding method above, which is the secondary event method. The purpose is to decouple the strong dependence between HTML and Js
(2) Questions
But if we just use method 3 directly for our Js programming, it is not enough because we will encounter the following problems
1. Browser compatibility, browsers supported by IE series and W3C are inconsistent with the method names and parameters of secondary event binding
2. After level 2 event binding, you cannot know whether others have bound events to the same element, what events have been bound, and what is the content of the event?
3. After the level 2 event binding method is triggered, the order is not in the order before binding, but is executed randomly. However, sometimes, we need to trigger the method in order
4. When an event of the same element is triggered, there is no w3c standard API that supports stopping and continuing to trigger other events bound to the same element. W3c supports stopping bubbling
5. Many times, we register level 2 events through anonymous functions, leaving no handle to the registered event execution method, so it is difficult to cancel the event through removeEventListener
(3) How to solve it with Kit
ok, the js framework exists to solve the above problems, let us see how the kit handles the above problems.
In the API of kit.js, there is an ev(config) method
This method accepts a Map type object, which contains 4 important parameters,
el element that needs to be bound
String event type
fn method to trigger execution
Scope can be omitted. Do you need to specify this pointer? If not, pass in the el during registration as this pointer
(4) Code Analysis
Let’s take a closer look at the code implementation
Look directly from the core part
If the incoming parameter is not empty, create an object on the el of the incoming parameter to save the event registration evReg of KitJs
There are two sub-objects in the evReg object, one is called evRegEv, which saves registered events
In the evRegEv object, save a key as the current registration event, and the value as an array. The config parameters passed in by method ev are placed in the array in first-come, first-served order. Note that this is an array! ! ! Because arrays can preserve the order, this is very important
There is also an anonymous method called evRegFn, which saves the event triggered,
We can see that evRegFn is an anonymous event. At the beginning, it will determine whether the global variable window[me.CONSTANTS.KIT_EVENT_STOPIMMEDIATEPROPAGATION] == true. If it is true, it will return and will not continue execution.
Looking down, he will receive the EV object triggered by the event, and use mergeIf to attach many objects to this EV, such as target, currentTarget, and relatedTarget to solve browser compatibility issues
And stopNow, stopDefault, stopGoOn are methods created to prevent events from continuing to trigger.
The following paragraph is the key to evRegFn. We will loop through the event array in the previously created evRegEv, in order, take out the config parameters passed in by the previous ev method, and execute the method in the config parameter. If the method returns If the value is not empty, return its return value
Finally make a browser compatible one and bind our evRegFn anonymous method using level 2 events.
(5) Summary
To put it simply, Kit uses its own anonymous method to cache event registration handles into an array, so that it can remember the order of events and provide an entrance to find out previously registered events, parameters, and methods. Etc. At the same time, compatibility is made for browser compatibility.
(6) Logout event
With Kit helping to cache event handles, logging out becomes easy
You can see that Kit finds the corresponding event config through direct comparison, fn.toString comparison, and fn.toString().trim() comparison, and deletes it from the array
(7) Event enhancement
Everyone should have noticed just now that Kit performed a mergeIf operation on the system's Event object. First of all, why do we need to do megerIf? Because the system's Event object attributes are Readonly and cannot be overwritten. We can only add attributes that it does not have
So Kit can only megerIf. We all know that there is an incompatibility in the Event Object of various browsers, so Kit needs to fix these incompatibilities. For example, IE does not have a target attribute, only srcElement, and we can add it to it. Add the target attribute to achieve W3c standard compatibility
Of course, mere repair cannot meet our needs. Many times, we also need to do a little fattening of the Event object
For example, when developing touchdown and touchmove on iPhone, we often need to get the offset of a single finger, and to get the offset of a single finger, we need code like ev.targetTouches[0].clientX, but once it is anonymous The function is like this, and it is incompatible on PC,
What to do, it doesn’t matter, we can give Event Object mergeIf our own attributes
firstFingerClientX and so on, so that we can easily unify the code developed on the mobile side and PC side.
Including, the next article will talk about HTML5 drag and drop, and advanced gesture events are all based on this foundation.
To add, why don’t you create your own Event like ExtJs? It’s because
1. The system’s native objects have a certain inheritance relationship and do not want to be destroyed
2. If you use your own new Object, it may cause the code to be non-portable after it leaves the framework, and the code content needs to be changed again