Event 系列: jquery event 源码
-
-
-
-
-
-
- jQuery.event = {
-
-
- add : function(elem, types, handler, data) {
- if (elem.nodeType == 3 || elem.nodeType == 8)
- return;
-
-
- if (jQuery.browser.msie && elem.setInterval)
- elem = window;
-
-
- if (!handler.guid)
- handler.guid = this.guid++;
-
-
- if (data != undefined) {
- var fn = handler;
- handler = this.proxy(fn, function() {
- return fn.apply(this, arguments);
- });
- handler.data = data;
- }
-
-
- var events = jQuery.data(elem, "events")
- || jQuery.data(elem, "events", {}),
-
- handle = jQuery.data(elem, "handle")
- || jQuery.data(elem, "handle", function() {
-
- if (typeof jQuery != "undefined"
- && !jQuery.event.triggered)
- return jQuery.event.handle.apply(
- arguments.callee.elem, arguments);
- });
-
- handle.elem = elem;
-
-
- jQuery.each(types.split(/\s+/), function(index, type) {
-
- var parts = type.split(".");
- type = parts[0];
- handler.type = parts[1];
-
-
- var handlers = events[type];
-
- if (!handlers) {
- handlers = events[type] = {};
-
-
- if (!jQuery.event.special[type]
- || jQuery.event.special[type].setup
- .call(elem, data) === false) {
-
- if (elem.addEventListener)
- elem.addEventListener(type, handle, false);
- else if (elem.attachEvent)
- elem.attachEvent("on" + type, handle);
- }
- }
-
-
-
- handlers[handler.guid] = handler;
-
-
- jQuery.event.global[type] = true;
- });
-
-
- elem = null;
- },
-
- guid : 1,
- global : {},
-
-
- remove : function(elem, types, handler) {
- if (elem.nodeType == 3 || elem.nodeType == 8)
- return;
-
- var events = jQuery.data(elem, "events"), ret, index;
-
- if (events) {
-
- if (types == undefined
- || (typeof types == "string" && types.charAt(0) == "."))
- for (var type in events)
- this.remove(elem, type + (types || ""));
- else {
-
- if (types.type) {
- handler = types.handler;
- types = types.type;
- }
-
-
- jQuery
- .each(types.split(/\s+/), function(index, type) {
-
- var parts = type.split(".");
- type = parts[0];
-
- if (events[type]) {
- if (handler)
- delete events[type][handler.guid];
- else
- for (handler in events[type])
- if (!parts[1]
- || events[type][handler].type == parts[1])
- delete events[type][handler];
-
-
- for (ret in events[type])
- break;
- if (!ret) {
- if (!jQuery.event.special[type]
- || jQuery.event.special[type].teardown
- .call(elem) === false) {
- if (elem.removeEventListener)
- elem.removeEventListener(type,
- jQuery.data(elem,
- "handle"),
- false);
- else if (elem.detachEvent)
- elem.detachEvent("on" + type,
- jQuery.data(elem,
- "handle"));
- }
- ret = null;
- delete events[type];
- }
- }
- });
- }
-
-
- for (ret in events)
- break;
- if (!ret) {
- var handle = jQuery.data(elem, "handle");
- if (handle)
- handle.elem = null;
- jQuery.removeData(elem, "events");
- jQuery.removeData(elem, "handle");
- }
- }
- },
-
- trigger : function(type, data, elem, donative, extra) {
- data = jQuery.makeArray(data);
-
- if (type.indexOf("!") >= 0) {
- type = type.slice(0, -1);
- var exclusive = true;
- }
-
- if (!elem) {
- if (this.global[type])
- jQuery.each(jQuery.cache, function() {
-
- if (this.events && this.events[type])
- jQuery.event.trigger(type, data, this.handle.elem);
- });
- } else {
- if (elem.nodeType == 3 || elem.nodeType == 8)
- return undefined;
-
- var val, ret, fn = jQuery.isFunction(elem[type] || null),
-
- event = !data[0] || !data[0].preventDefault;
-
-
- if (event) {
- data.unshift( {
- type : type,
- target : elem,
- preventDefault : function() {
- },
- stopPropagation : function() {
- },
- timeStamp : now()
- });
- data[0][expando] = true;
- }
-
-
- data[0].type = type;
- if (exclusive)
- data[0].exclusive = true;
-
-
- var handle = jQuery.data(elem, "handle");
- if (handle)
- val = handle.apply(elem, data);
-
-
-
-
- if ((!fn || (jQuery.nodeName(elem, 'a') && type == "click"))
- && elem["on" + type]&& elem["on" + type].apply(elem, data) === false)
- val = false;
-
-
- if (event)
- data.shift();
-
-
- if (extra && jQuery.isFunction(extra)) {
-
- ret = extra.apply(elem, val == null ? data : data.concat(val));
-
-
- if (ret !== undefined)
- val = ret;
- }
-
-
- if (fn && donative !== false && val !== false
- && !(jQuery.nodeName(elem, 'a') && type == "click")) {
- this.triggered = true;
- try {
- elem[type]();
-
- } catch (e) {
- }
- }
-
- this.triggered = false;
- }
-
- return val;
- },
-
- handle : function(event) {
-
- var val, ret, namespace, all, handlers;
-
- event = arguments[0] = jQuery.event.fix(event || window.event);
-
-
- namespace = event.type.split(".");
- event.type = namespace[0];
- namespace = namespace[1];
-
- all = !namespace && !event.exclusive;
-
- handlers = (jQuery.data(this, "events") || {})[event.type];
-
- for (var j in handlers) {
- var handler = handlers[j];
-
-
- if (all || handler.type == namespace) {
-
- event.handler = handler;
- event.data = handler.data;
-
- ret = handler.apply(this, arguments);
-
- if (val !== false)
- val = ret;
-
- if (ret === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
-
- return val;
- },
-
- props : "altKey attrChange attrName bubbles button cancelable charCode clientX "
- + "clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode "
- + "metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX "
- + "screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which"
- .split(" "),
-
-
- fix : function(event) {
- if (event[expando] == true)
- return event;
-
-
- var originalEvent = event;
- event = {
- originalEvent : originalEvent
- };
-
- for (var i = this.props.length, prop;i;) {
- prop = this.props[--i];
- event[prop] = originalEvent[prop];
- }
-
- event[expando] = true;
-
-
- event.preventDefault = function() {
-
- if (originalEvent.preventDefault)
- originalEvent.preventDefault();
-
- originalEvent.returnValue = false;
- };
- event.stopPropagation = function() {
-
- if (originalEvent.stopPropagation)
- originalEvent.stopPropagation();
-
- originalEvent.cancelBubble = true;
- };
-
-
- event.timeStamp = event.timeStamp || now();
-
-
- if (!event.target)
- event.target = event.srcElement || document;
- if (event.target.nodeType == 3)
- event.target = event.target.parentNode;
-
-
- if (!event.relatedTarget && event.fromElement)
- event.relatedTarget = event.fromElement == event.target
- ? event.toElement
- : event.fromElement;
-
-
- if (event.pageX == null && event.clientX != null) {
- var doc = document.documentElement, body = document.body;
- event.pageX = event.clientX
- + (doc && doc.scrollLeft || body && body.scrollLeft || 0)
- - (doc.clientLeft || 0);
- event.pageY = event.clientY
- + (doc && doc.scrollTop || body && body.scrollTop || 0)
- - (doc.clientTop || 0);
- }
-
-
- if (!event.which
- && ((event.charCode || event.charCode === 0)
- ? event.charCode
- : event.keyCode))
- event.which = event.charCode || event.keyCode;
-
-
- if (!event.metaKey && event.ctrlKey)
- event.metaKey = event.ctrlKey;
-
-
-
- if (!event.which && event.button)
- event.which = (event.button & 1 ? 1 : (event.button & 2
- ? 3
- : (event.button & 4 ? 2 : 0)));
-
- return event;
- },
-
- proxy : function(fn, proxy) {
-
- proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
- return proxy;
- },
-
- special : {
- ready : {
-
- setup : bindReady,
- teardown : function() {
- }
- }
- }
- };
-
- if (!jQuery.browser.msie) {
-
-
- var withinElement = function(event) {
-
- var parent = event.relatedTarget;
-
- while (parent && parent != this)
- try {
- parent = parent.parentNode;
- } catch (e) {
- parent = this;
- }
-
- if (parent != this) {
-
- event.type = event.data;
-
- jQuery.event.handle.apply(this, arguments);
- }
- };
-
- jQuery.each( {
- mouseover : 'mouseenter',
- mouseout : 'mouseleave'
- }, function(orig, fix) {
- jQuery.event.special[fix] = {
- setup : function() {
- jQuery.event.add(this, orig, withinElement, fix);
- },
- teardown : function() {
- jQuery.event.remove(this, orig, withinElement);
- }
- };
- });
- }
-
- jQuery.fn.extend( {
- bind : function(type, data, fn) {
- return type == "unload" ? this.one(type, data, fn) : this
- .each(function() {
- jQuery.event.add(this, type, fn || data, fn && data);
- });
- },
-
-
-
-
-
- one : function(type, data, fn) {
- var one = jQuery.event.proxy(fn || data, function(event) {
- jQuery(this).unbind(event, one);
- return (fn || data).apply(this, arguments);
- });
- return this.each(function() {
- jQuery.event.add(this, type, one, fn && data);
- });
- },
-
-
-
-
-
-
- unbind : function(type, fn) {
- return this.each(function() {
- jQuery.event.remove(this, type, fn);
- });
- },
-
-
- trigger : function(type, data, fn) {
- return this.each(function() {
- jQuery.event.trigger(type, data, this, true, fn);
- });
- },
-
- triggerHandler : function(type, data, fn) {
- return this[0]
- && jQuery.event.trigger(type, data, this[0], false, fn);
- },
-
-
- toggle : function(fn) {
- var args = arguments, i = 1;
-
- while (i < args.length)
- jQuery.event.proxy(fn, args[i++]);
-
- return this.click(jQuery.event
- .proxy(fn, function(event) {
- this.lastToggle = (this.lastToggle || 0) % i;
- event.preventDefault();
-
-
-
-
- return args[this.lastToggle++].apply(this,
- arguments) || false;
- }));
- },
-
-
-
-
-
-
- hover : function(fnOver, fnOut) {
- return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
- },
-
-
- ready : function(fn) {
- bindReady();
- if (jQuery.isReady)
- fn.call(document, jQuery);
- else
-
- jQuery.readyList.push(function() {
- return fn.call(this, jQuery);
- });
-
- return this;
- }
- });
-
- jQuery.extend( {
- isReady : false,
- readyList : [],
-
- ready : function() {
- if (!jQuery.isReady) {
- jQuery.isReady = true;
-
- if (jQuery.readyList) {
- jQuery.each(jQuery.readyList, function() {
- this.call(document);
- });
- jQuery.readyList = null;
- }
-
- jQuery(document).triggerHandler("ready");
- }
- }
- });
-
- var readyBound = false;
-
- function bindReady() {
- if (readyBound)
- return;
- readyBound = true;
-
-
- if (document.addEventListener && !jQuery.browser.opera)
-
- document.addEventListener("DOMContentLoaded", jQuery.ready, false);
-
-
- if (jQuery.browser.msie && window == top)
- (function() {
- if (jQuery.isReady)
- return;
- try {
-
-
- document.documentElement.doScroll("left");
- } catch (error) {
-
- setTimeout(arguments.callee, 0);
- return;
- }
- jQuery.ready();
- })();
-
- if (jQuery.browser.opera)
- document.addEventListener("DOMContentLoaded", function() {
- if (jQuery.isReady)
- return;
-
- for (var i = 0;i < document.styleSheets.length; i++)
- if (document.styleSheets[i].disabled) {
- setTimeout(arguments.callee, 0);
- return;
- }
- jQuery.ready();
- }, false);
-
- if (jQuery.browser.safari) {
- var numStyles;
- (function() {
- if (jQuery.isReady)
- return;
-
- if (document.readyState != "loaded"
- && document.readyState != "complete") {
- setTimeout(arguments.callee, 0);
- return;
- }
-
- if (numStyles === undefined)
- numStyles = jQuery("style, link[rel=stylesheet]").length;
- if (document.styleSheets.length != numStyles) {
- setTimeout(arguments.callee, 0);
- return;
- }
- jQuery.ready();
- })();
- }
-
-
- jQuery.event.add(window, "load", jQuery.ready);
- }
-
-
- jQuery
- .each(
- ("blur,focus,load,resize,scroll,unload,click,dblclick,"
- + "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + "submit,keydown,keypress,keyup,error")
- .split(","), function(i, name) {
- jQuery.fn[name] = function(fn) {
- return fn ? this.bind(name, fn) : this.trigger(name);
- };
- });
-
-
-
-
- jQuery(window).bind('unload', function() {
- for (var id in jQuery.cache)
-
- if (id != 1 && jQuery.cache[id].handle)
- jQuery.event.remove(jQuery.cache[id].handle.elem);
- });
原文地址:https://www.cnblogs.com/rooney/p/1346132.html