This lesson is mainly to explain the source code interpretation of JQuery.event.trigger.
Trigger = function (event, data, Elem, onlyhandlers) {
if (elem && = = = 3 | | Elem.nodetype ===8)) { //triggered element node cannot be a text node and comment node
Return
}
var cache, exclusive, I, cur, old, ontype, special, handle, Eventpath, bubbletype, type = Event.type | | Event, namespaces =[];
.....
if (Type.indexof (".") >= 0) { //If the event type has a dot number, it represents a namespace, so you need to break out the namespace
namespaces = Type.split (".");
Type = Namespaces.shift ();
Namespaces.sort ();
}
if ((!elem | | jQuery.event.customEvent [type]) &&!jquery.event.global[type]) { //If the element does not exist or the event type is a custom event, and has never been bound to this type of event before, then return directly.
Return
}
....
Ontype = Type.indexof (":") < 0? " On "+ Type:" "; //If the event type does not have: character, it proves to be a ontype binding event
if (!elem) { //If no triggering element is indicated, the entire cache system is searched
cache = Jquery.cache;
For (i in cache) {
if (cache[i].events && cache[i].events[type]) { //from the cache system, find the corresponding events property and find the Events[type to trigger the event Type]
JQuery.event.trigger (event,data,cache[i].handle.elem,true); //Triggers all callback methods that are bound to this event type.
}
}
Return //Direct return
}
Event.result = undefined; //Clear the event's result property for easy reuse.
if (!event.target) {
Event.target = Elem;
}
data = Data!=null? Jquery.makearray (data): []; //If the parameter is passed in, convert the parameter to the array type
Data.unshift (event); //Put the event object into the first item of the array
Special = Jquery.event.special[type] | | {}; ///event type requires special handling, such as: Mousescroll event
if (Special.trigger && special.trigger.apply (elem,data) = = = False) { //If the event type already has a trigger method, call it, If the returned result is false, it is returned directly.
Return
}
Eventpath = [[Elem, Special.bindtype | | type]]; //Plan The Bubbling path, from the current element to the window
if (!onlyhandlers &&!special.nobubble &&!jquery.iswindow (elem)) { //If the event type of the element does not block bubbling, And the element is not a window object, a bubbling simulation is necessary.
Bubbletype = Special.delegatetype | | Type //Get the type of event
cur = elem.parentnode;
for (old = elem; cur; cur = cur.parentnode) { //The current element is bubbled with all parent elements, one event type at a time. Suppose Div1 (the current element, triggering the Click event) has a div2,div2 above it with Body,body above html,html with document on it. Then the Eventpath array is: [[Div1,click],[div2,click],[body,click],[html,click],[document,click]]
Eventpath.push ([cur, bubbletype]);
old = cur;
}
if (old = = (Elem.ownerdocument | | document)) { //When old is document, cur is empty and exits the loop
Eventpath.push ([Old.defaultview | | old.parentwindow | | window, bubbletype]); //Simulate bubbling to Window object
}
}
For (i=0;i<eventpath.length&&!event.ispropagationstopped (); i++) { //along the above-planned bubbling route, Triggers a callback of the specified type event for the passed element node to be executed individually
cur = eventpath[i][0]; //Element
Event.type = eventpath[i][1] //Event Type
Handle = (Jquery._data (cur, "events") | | {}) [Event.type] && jquery._data (cur, "handle"); ///First determine if there is a callback method for this event type that is bound by this element in the cache system, and if so, take it out.
if (handle) {//Execute these callback methods
Handle.apply (Cur,data);
}
handle = Ontype && Cur[ontype]; //If there is onxxx bound callback, whether it is written in JS, or HTML tags, will be taken to
if (Handle && jquery.acceptdata (cur) && handle.apply && handle.apply (cur, data) = = = = False) {/ /If handle is not empty and the current element can bind data, and handle has the Apply method, the handle callback method is executed, and if the current callback returns false, the default event is blocked.
Event.preventdefault ();
}
}
Event.type = type;
if (!onlyhandlers &&!event.isdefaultprevented ()) { //If the Preventdefault method is not executed, Or the handle method above returns False (which also blocks the default event). The default behavior is simulated. The concrete refers to the simulation: Submit,blur,focus,select,reset,scroll and other methods.
if ((!special._default | | special._default.apply (elem.ownerdocument,data) = = = False) && //If the user specifies the default behavior, Executes the specified default behavior, and if the specified default behavior returns FALSE, continue to determine the following condition
! (Type = = = "click" && jquery.nodename (Elem, "a")) && //If the event type is click and is triggered on a label, it does not perform its default behavior, otherwise it continues to judge
Jquery.acceptdata (Elem)) { //If the current element can bind data
if (Ontype && Elem[type] && //If the element has a onxxx callback and the element has a type method, such as: <input type = "Submit" onsubmit= " function () {} ", it has onxxx callback method, also has Input.submit method, so continue to judge
((type!== "Focus" && type!== "blur") | | event.target.offsetWidth!==0) && //If the event type is not Focus,blur. Or the event type is Focu,blur, but the element that triggered the event is not hidden (the hidden element, which has a offsetwidth of 0), continues to be judged. (The focus and blur default behavior that triggers the hidden element, Ie6-8 throws an error.) )
!jquery.iswindow (Elem)) { //not the window element enters the IF statement to perform the default behavior. (The default behavior of window triggers, there will be problems, such as: Window.Scroll method, in IE and standard browser differences, IE will default scroll () method is scroll (0,0))
Old = Elem[ontype];
if (old) {
Elem[ontype] = null; //onxxx's callback has been executed, so you don't have to do it again.
}
jQuery.event.triggered = type; //Identity is triggering this event type to prevent the following elem [Type] () from repeating the Dispatch method
Elem [Type] (); //execute default behavior, such as: Input[submit] (), the INPUT element's commit method. By clicking input of type Submint, the Submit property method is executed by default. However, the dispatch method is not called here.
jQuery.event.triggered = undefined; //Restore
if (old) {
Elem[ontype] = old;
}
}
}
}
return event.result;
}
Generally speaking, trigger is the dispatch of the enhanced version. Dispatch only triggers a callback for the current element with its underlying element (through the event proxy). Trigger is the simulation of the entire bubbling process, in addition to itself, triggering its ancestor node and window of the same type of callback. But judging from trigger's code, what it does more than dispatch is the default behavior of triggering events. The trigger thing to do is to trigger a callback (dispatch) on an element, and then let it bubble, triggering other callbacks (dispatch) on the line.
The browser provides a native distribution mechanism, IE is called fireevent, and the standard browser is dispatchevent. ie the problem is that there are many events can not bubble or bubble to the top layer, if we put the code of IE independent, standard browser with a set, ie with a set (old version IE,IE9 in the standard mode support Dispatchevent method), so performance greatly improved. That's what Zepto.js did.
When creating a universal event object, it should be document.createevent ("events"), but early browsers need to use Document.createevent ("htmlevents");
A universal event should be able to trigger callbacks for all events, but mouse events are created using the mouseevents parameter to create a mouse object event.
Firefox does not support MouseWheel, we need to create Dommousescroll event objects with Document.createevent ("Mousescrollevents").
Come on!
25th Lesson: Event System 4