Starting from today's chapter, I will focus on introducing the content of KitJs' event management, and try to expose to you in simple language how the mainstream js framework implements its own independent event management function internally.
(I) Ordinary Dom Events
We can generally write events in HTML by supporting
<a onclick=”alert(1)”>test</a>
Or bind after getting the dom object
document.getElementById('a').onclick=function(){alert(1)}
Or secondary events
document.getElementById('a').addEventListener('click',function(){alert(1)},flase)
Or via script tag
<script for=”a” event=”onclick”>alert(1)</script>
The W3C standard recommends the above third method of binding, which is a secondary event method, with the purpose of decoupling the strong dependence of HTML and Js
(II) Question
However, if we only use Mode 3 to directly perform our Js programming, it is not enough, because we will encounter the following problems
1. Browser compatibility. The parameters of the browser supported by IE series and W3C are not consistent for the second-level event binding method names and parameters.
2. After binding through level 2 events, you cannot know whether others have bound events to the same element, which events have been bound, and what is the content of the event?
3. After the method of binding of level 2 events is triggered, the order is not in the order before the binding, but is executed randomly. However, sometimes, we need to order the triggered methods.
4. When the event of the same element is triggered, the standard API of w3c does not support stopping and continuing to trigger other events bound to the same element, w3c supports stopping bubbles.
5. Many times, we register a level 2 event through anonymous function method, and no handle to register the event execution method is left, so it is difficult to cancel the event through removeEventListener.
(III) How to solve the problem of Kit
OK, the js framework exists to solve the above problems. Let's see how kit handles the above problems.
In the kit.js API, 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 triggers execution method
scope can be omitted, whether this pointer needs to be specified, if none, the el at the time of registration is passed as this pointer
(IV) Code analysis
Let's take a look at the code implementation further
Start directly from the core part
If the incoming parameter is not empty, an object is created on the incoming parameter el to save the event registration of KitJs evReg
There are two child objects in the evReg object, one is called evRegEv, which saves the registered event
In the evRegEv object, save a key as the current registered event, and the value is an array. In the array, put the config parameters passed in the method ev in the order of first and then arrival. Note that this is an array! ! ! Because arrays can save order, this is very important
There is also an anonymous method called evRegFn, which saves event triggers.
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] is ==true. If true, it will return and will not continue to execute.
Then look down, it will accept the EV object triggered by the event and attach many objects to the EV using mergeIf, such as target, currentTarget, relatedTarget, to solve the browser compatibility problem.
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 evRegEv created before, take out the config parameters passed in the previous ev method in order, and execute the method in the config parameter. If the return value of the method is not empty, it will return its return value.
Finally, we make a browser compatible and bind our evRegFn anonymous method using a level 2 event method.
(V) Summary
Simply put, Kit uses its own anonymous method to cache the event registration handle and enter an array, so that it can remember the sequence of events, as well as provide an entry to find out the previously registered events, parameters, methods, etc., and at the same time it is compatible with browser compatibility.
(VI) Logout Event
With Kit help cache event handles, logging out becomes simple
You can see that Kit finds the corresponding event config through direct comparison, or fn.toString comparison, and fn.toString().trim() comparison, and deletes it from the array
(VII) Event enhancement
You should have noticed just now that Kit has done a mergeIf operation on the system Event object. First of all, why do you need to do megerIf? Because the object properties of the system Event object are Readonly and cannot be overwritten, you can only add properties that it does not have.
So Kit can only megerIf. We all know that there is an incompatibility of Event Object of each browser's event object, so Kit needs to fix these incompatibility. For example, IE does not have a target attribute, only srcElement. We can add target attribute to it to achieve compatibility of W3c standard
Of course, just repair cannot meet our needs. Many times, we still need to make a little weight gain for the Event object.
For example, when developing touchdown and touchmove on iPhone, we often need to get single-finger offsets, and to get single-finger offsets, ev.targetTouches[0].clientX, such code, but once the anonymous function is like this, it will be incompatible on the PC.
What to do? It doesn't matter, we can give Event Object mergeIf our own attributes
firstFingerClientX, etc., so we can easily implement the unified code developed by mobile and PC.
Including, the next article will talk about HTML5 drag and drop, and advanced gesture events are based on this basis.
Add to this, why not new one's own Event like ExtJs is because
1. The system native object has a certain inheritance relationship and does not want to be destroyed.
2. If you use your own new Object, the code may be unportable after it is out of the framework, and the code content needs to be changed again.