There are many ways to bind events, using jquery as a way of binding (Elem.click = function () {...}) I don't really want to recommend it to everyone. The main reason is that ELEM.CLICK=FN can only bind to one event processing, and multiple bindings will only hold the result of the last binding.
Here are some ways to introduce the jquery binding event.
Copy Code code as follows:
JQuery.fn.eventType ([[Data,] fn])
For example, EventType refers to the type of event, such as click: $ ("#chua"). Click (FN);
Data This parameter is generally not used. This way events are bound to ("#chua") without delegate events, and JS native event bindings are closer. Let's take a look at the source
Jquery.each (Blur focus focusin focusout Load resize scroll unload click DblClick "+
" MouseDown MouseUp mousemove m Ouseover mouseout mouseenter mouseleave "+
" Change Select Submit KeyDown keypress error KeyUp "). Split (" " ), function (i, name) {
//merge 15 kinds of events to Jquery.fn, internal call This.on/this.trigger
jquery.fn[name] = funct Ion (data, FN) {return
arguments.length > 0?
This.on (name, NULL, data, FN):
//If the specified event
This.trigger (name) is immediately triggered without parameters;
};
});
JQuery.fn.bind (types[, data], FN)
such as $ ("#chua"). Bind ("click", fn). The event is bound directly to $ ("#chua") without a delegate event. Source
Bind:function (types, data, fn) {return
this.on (types, NULL, data, FN);
},
unbind:function (types, fn {return
This.off (types, NULL, FN);
}
JQuery.fn.delegate (selector, types[, data], FN)
As the name implies delegate this function is used to do event delegates, the selector selector corresponding response processing is delegated to the elements that are matched by the current jquery.
For example: $ (document). Delegate (' #big ', "click", Dohander); analyze here and analyze the process of the event delegate.
When you click on the "#big" element, the event click Bubbles until the document node.
Document binds the handling event, which is invoked to the event dispatcher dispatch;
Dispatch all the delegate events list handlers the corresponding event type click;
According to the event source Event.target filter out the selector attribute of each element in the delegate event list handlers the node that corresponds to the delegate event between the event original and the delegate node document (including the event source) is saved as a handlerqueue;
Perform the event handling within the Handlerqueue.
The above is a rough process, followed by a detailed analysis. First look at the delegate source
Delegate:function (selector, types, data, fn) {return
This.on (types, selector, data, FN);
},
undelegate: function (selector, types, fn) {
//(namespace) or (selector, types [, FN]) return
arguments.length = 1? t His.off (Selector, "* *"): This.off (types, selector | | "* *", FN);
}
JQuery.fn.one (types[, selector[, data]], FN)
Event-handling functions that are bound by one () function are one-time, and are executed only when the event is first triggered. Once triggered, jquery removes the current event binding.
such as $ ("#chua"). One ("click", fn); bind a one-time click event for the #chua node
$ (document). One ("click", "#chua", FN); delegate the #chua click event to document processing. Source
One:function (types, selector, data, FN) {return
This.on (types, selector, data, FN, 1);
}
JQuery.fn.trigger (type[, data])
JQuery.fn.triggerHandler (type[, data)
Trigger triggers the type of event for each element corresponding to the jquery object. such as $ ("#chua"). Trigger ("click");
Triggehandler triggers only events of type type for the first element in the element that matches the jquery object, and does not trigger the default behavior of the event.
Immediately triggers the event
trigger:function (type, data) {return
This.each (function () {
) of all elements within the jquery object of the specified type. JQuery.event.trigger (type, data, this);}
;
///immediately triggers the event of the specified type of the first element within the jquery object and does not trigger the default behavior of the event (such as form submission)
triggerhandler:function (type, data) {
var elem = this[0];
if (elem) {return
JQuery.event.trigger (type, data, Elem, True);
}
The above analysis of some of the event binding, there is no find that they are using the. On mode of binding? This is why it is the reason to advocate for unified use on to bind (except one).
JQuery.fn.on (types[, selector[, data]], FN)
A. On event binding half of the code is actually handling the handling of passing different parameters, which is also the cost of jquery's slogan write less. Finally, the jQuery.event.add is used to bind the event.
There are several key points to JQuery.event.add binding events:
First, use internal caching to save event information for node Elem
Gets the cached data
Elemdata = Jquery._data (elem);
...
Sets the cached data
if (!) ( events = elemdata.events)) {
events = Elemdata.events = {};
}
if (!) ( Eventhandle = Elemdata.handle)) {
Eventhandle = Elemdata.handle = function (e) {
...
};
Use Elem as a feature of the handle function to prevent memory leaks caused by IE non-local events
eventhandle.elem = Elem;
}
The second is to set the binding event information, especially the specified selector selector, response processing handler, response event type type, namespace namespace
Handleobj: Sets the binding event information. Throughout the event handling
Handleobj = Jquery.extend ({
type:type,
origtype:origtype,
data:data,
handler: Handler,
Guid:handler.guid,
selector:selector,
//for use in libraries implementing. Is (). We Use this as POS matching in ' select '
//' Needscontext ': New RegExp ("^" + whitespace + "*[>+~]|:( Even|odd|eq|gt|lt|nth|first|last) (?: \ \ ("+
//whitespace +" * (?:-\ \d) \\d*) "+ whitespace +" *\\) |) (? =[^-]|$) "," I ")
//used to judge intimate relationships
Needscontext:selector && jQuery.expr.match.needsContext.test ( selector),
namespace:namespaces.join (".")
}, Handleobjin);
Third, in the node's list of events, the real delegate event list is placed in front, and the Delegatecount attribute is synchronized, that is, the events.click.length assumption is that the 3,events.click.delegatecount is assumed to be 2. The events specified by events.click[0] and events.click[1] are delegate events. The third events.click[2] corresponds to an event that is not a delegate event, but an event of the node itself.
Adds the event object handleobj to the processing list of the elements, the delegate event is placed ahead, and the delegate-agent count increments
if (selector) {
handlers.splice (handlers.delegatecount++, 0, handleobj);
} else {
Handlers.push (handleobj);
}
Source code and after adding the structure of the event has been analyzed, please click to view the details
Binding has a common function jQuery.fn.on. Uncoupling also has a common function jQuery.fn.off
JQuery.fn.off ([types[, selector][, FN]])
The reference here has a special case: When types is a browser event object event, it means to remove (BIND) The delegate event Event.selector specified on the delegation node
The arguments passed in are events and the handler function
if (types && types.preventdefault && types.handleobj) {
//(event) Dispatch ed jquery.event
handleobj = types.handleobj;
Types.delegatetarget is the event managed Object
jquery (types.delegatetarget). Off (
//combining jquery recognized type
Handleobj.namespace? Handleobj.origtype + "." + HandleObj.namespace:handleObj.origType,
handleobj.selector,
Handleobj.handler
);
return this;
}
In any case, the JQuery.event.remove function is invoked to solve the binding event.
JQuery.fn.off Complete source code is as follows
Off:function (types, selector, fn) {var handleobj, type; The passed in parameter is an event and the handler function is bound to the if (types && types.preventdefault && types.handleobj) {//(event) dispatched J
Query.event handleobj = types.handleobj; Types.delegatetarget is the event managed object jquery (Types.delegatetarget). Off (///combining jquery recognized type handleobj.namespace? handleob
J.origtype + "." + HandleObj.namespace:handleObj.origType, Handleobj.selector, Handleobj.handler);
return this; } if (typeof types = = = "Object") {//(Types-object [, selector]) for (type in types) {This.off (type, sel
Ector, types[type]);
return to this;
} if (selector = = False | | typeof selector = = "function") {//(types [, fn]) fn = selector;
selector = undefined;
} if (fn = false) {fn = Returnfalse;
Return This.each (function () {JQuery.event.remove (this, types, FN, selector);
}); }
Next, analyze the low-level API JQuery.event.remove for event binding.
JQuery.event.remove
jquery uses the. Off () function when an event bound by an injury is an internal call to the underlying function of JQuery.event.remove. The process flow of this function is as follows
1. Decompose the incoming event type types, traversal type, if the event to be deleted does not have an event name, only the namespace indicates that all binding events under that namespace are deleted
decomposes types to Type.namespace as an array of unit elements
types = (Types | | ""). Match (core_rnotwhite) | | [""];
t = types.length;
while (t--) {
tmp = rtypenamespace.exec (types[t]) | | [];
Type = Origtype = tmp[1];
namespaces = (Tmp[2] | | ""). Split ("."). Sort ();
types[all events on the current namespace (T]) of the current element (
!type) {for
(type in events) {
jQuery.event.remove (elem, type + types[T], handler, selector, true);
Continue;
}
...
2. The traversal type process, deletes matches the event, the proxy counts revises
Type = (selector special.delegateType:special.bindType) | | type;
handlers = events[Type] | | [];
TMP = tmp[2] && new RegExp ("(^|\\.)" + namespaces.join ("\. (?:. *\\.|)") + "(\\.| $)" );
Delete matching event
Origcount = j = handlers.length;
while (j--) {
handleobj = handlers[j];
Various conditions for removing events can be removed
if ((mappedtypes | | origtype = = handleobj.origtype) &&
(!handler | | handler.guid = = = Handleobj.guid) &&
(!tmp | | tmp.test (handleobj.namespace)) &&
(!selector | | selector = = Handleobj.selector | | selector = = "* *" && handleobj.selector)) {
Handlers.splice (j, 1);
if (handleobj.selector) {
handlers.delegatecount--;
}
if (special.remove) {
special.remove.call (elem, handleobj);
}
}
}
3. If the event handler for the specified type on the node is already empty, remove the event handling object of that type on the events
Remove event handling Objects
//(Remove potential infinite recursion during special event handling, the next chapter will specifically address this situation)
if (Origcount &&!handlers.length) {
//For example, VAR Js_obj = document.createelement ("div"); Js_obj.onclick = function () {...}
The js_obj above is a reference to a DOM element that has long been in the Web page and does not disappear, and this DOM element is a property of the onclick, the internal function reference (closure), and the anonymous function and the Js_ There is a hidden association (scope chain) between obj so that a circular reference is formed.
if (!special.teardown | | special.teardown.call (elem, namespaces, elemdata.handle) = = False) {
Jquery.removeeven T (elem, type, elemdata.handle);
Delete events[type];
4. If there are no bound events on the node, empty the event handling portal handle
if (Jquery.isemptyobject (events)) {
delete elemdata.handle;
Removedata also checks whether the event object is empty, so use it instead of the delete
jquery._removedata (elem, "events");
}
Expansion: Browser Event deletion jquery.removeevent
Jquery.removeevent = Document.removeeventlistener?
function (elem, type, handle) {
if (elem.removeeventlistener) {
Elem.removeeventlistener (type, handle, false) ;
}
} :
function (Elem, type, handle) {
var name = ' on ' + type;
if (elem.detachevent) {
//#8545, #7054 to avoid the memory leaks in ie6-8
//DetachEvent The custom event needs to pass the first parameter, cannot be undefined
if ( typeof elem[Name] = = = core_strundefined) {
elem[name] = null;
}
Elem.detachevent (name, handle);
}
;
The above content is small series to introduce the jquery 1.9.1 Source Analysis Series (10) Event System binding event, I hope you like.