jquery 원본 jQuery의 2차 개발을 깊이 있게 배우다
41800 단어 Jquery 소스
jquery.js의 설계와 실현
(function (global, factory) {
if (typeof module === "object" && typeof module.exports === "object") {
module.exports = global.document ?
factory(global, true) :
function (w) {
if (!w.document) {
throw new Error("jQuery requires a window with a document");
}
return factory(w);
};
} else {
factory(global);
}
}(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
var deletedIds = [];
var slice = deletedIds.slice;
var concat = deletedIds.concat;
var push = deletedIds.push;
var indexOf = deletedIds.indexOf;
var class2type = {};
var toString = class2type.toString;
var hasOwn = class2type.hasOwnProperty;
var support = {};
var
version = "1.11.3",
// Define a local copy of jQuery
jQuery = function (selector, context) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init(selector, context);
},
// Support: Android<4.1, IE<9
// Make sure we trim BOM and NBSP
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
// Matches dashed string for camelizing
rmsPrefix = /^-ms-/,
rdashAlpha = /-([\da-z])/gi,
// Used by jQuery.camelCase as callback to replace()
fcamelCase = function (all, letter) {
return letter.toUpperCase();
};
jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
jquery: version,
constructor: jQuery,
// Start with an empty selector
selector: "",
// The default length of a jQuery object is 0
length: 0,
toArray: function () {
return slice.call(this);
}
// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: push,
sort: deletedIds.sort,
splice: deletedIds.splice
};
jQuery.extend = jQuery.fn.extend = function () {
var src, copyIsArray, copy, name, options, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
// Handle a deep copy situation
if (typeof target === "boolean") {
deep = target;
// skip the boolean and the target
target = arguments[i] || {};
i++;
}
// Handle case when target is a string or something (possible in deep copy)
if (typeof target !== "object" && !jQuery.isFunction(target)) {
target = {};
}
// extend jQuery itself if only one argument is passed
if (i === length) {
target = this;
i--;
}
for (; i < length; i++) {
// Only deal with non-null/undefined values
if ((options = arguments[i]) != null) {
// Extend the base object
for (name in options) {
src = target[name];
copy = options[name];
// Prevent never-ending loop
if (target === copy) {
continue;
}
// Recurse if we're merging plain objects or arrays
if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
if (copyIsArray) {
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : [];
} else {
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
target[name] = jQuery.extend(deep, clone, copy);
// Don't bring in undefined values
} else if (copy !== undefined) {
target[name] = copy;
}
}
}
}
// Return the modified object
return target;
};
jQuery.extend({
// Unique for each copy of jQuery on the page
expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
// Assume jQuery is ready without the ready module
isReady: true,
error: function (msg) {
throw new Error(msg);
},
isWindow: function (obj) {
/* jshint eqeqeq: false */
return obj != null && obj == obj.window;
},
// Support: Android<4.1, IE<9
trim: function (text) {
return text == null ?
"" :
(text + "").replace(rtrim, "");
},
// jQuery.support is not used in Core but other projects attach their
// properties to it so it needs to exist.
support: support
});
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (i, name) {
class2type["[object " + name + "]"] = name.toLowerCase();
});
var Sizzle =
/*!
* Sizzle CSS Selector Engine v2.2.0-pre
* http://sizzlejs.com/
*
* Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2014-12-16
*/
(function (window) {
// Optimize for push.apply( _, NodeList )
try {
push.apply(
(arr = slice.call(preferredDoc.childNodes)),
preferredDoc.childNodes
);
// Support: Android<4.0
// Detect silently failing push.apply
arr[preferredDoc.childNodes.length].nodeType;
} catch (e) {
push = {
apply: arr.length ?
// Leverage slice if possible
function (target, els) {
push_native.apply(target, slice.call(els));
} :
// Support: IE<9
// Otherwise append directly
function (target, els) {
var j = target.length,
i = 0;
// Can't trust NodeList.length
while ((target[j++] = els[i++])) { }
target.length = j - 1;
}
};
}
})(window);
function Sizzle(selector, context, results, seed) {
// All others
return select(selector.replace(rtrim, "$1"), context, results, seed);
}
jQuery.find = Sizzle;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.pseudos;
jQuery.unique = Sizzle.uniqueSort;
jQuery.text = Sizzle.getText;
jQuery.isXMLDoc = Sizzle.isXML;
jQuery.contains = Sizzle.contains;
support = Sizzle.support = {};
// Support: IE<8
// Verify that getAttribute really returns attributes and not properties
// (excepting IE8 booleans)
support.attributes = assert(function (div) {
div.className = "i";
return !div.getAttribute("className");
});
Sizzle.error = function (msg) {
throw new Error("Syntax error, unrecognized expression: " + msg);
};
// Implement the identical functionality for filter and not
function winnow(elements, qualifier, not) {
if (jQuery.isFunction(qualifier)) {
return jQuery.grep(elements, function (elem, i) {
/* jshint -W018 */
return !!qualifier.call(elem, i, elem) !== not;
});
}
if (qualifier.nodeType) {
return jQuery.grep(elements, function (elem) {
return (elem === qualifier) !== not;
});
}
if (typeof qualifier === "string") {
if (risSimple.test(qualifier)) {
return jQuery.filter(qualifier, elements, not);
}
qualifier = jQuery.filter(qualifier, elements);
}
return jQuery.grep(elements, function (elem) {
return (jQuery.inArray(elem, qualifier) >= 0) !== not;
});
}
jQuery.filter = function (expr, elems, not) {
var elem = elems[0];
if (not) {
expr = ":not(" + expr + ")";
}
return elems.length === 1 && elem.nodeType === 1 ?
jQuery.find.matchesSelector(elem, expr) ? [elem] : [] :
jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
return elem.nodeType === 1;
}));
};
jQuery.fn.extend({
filter: function (selector) {
return this.pushStack(winnow(this, selector || [], false));
}
});
// A central reference to the root jQuery(document)
var rootjQuery,
// Use the correct document accordingly with window argument (sandbox)
document = window.document,
// A simple way to check for HTML strings
// Prioritize #id over to avoid XSS via location.hash (#9521)
// Strict HTML recognition (#11290: must start with )[^>]*|#([\w-]*))$/,
init = jQuery.fn.init = function (selector, context) {
var match, elem;
// HANDLE: $(""), $(null), $(undefined), $(false)
if (!selector) {
return this;
}
return jQuery.makeArray(selector, this);
};
// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;
// Initialize central reference
rootjQuery = jQuery(document);
jQuery.extend({
sibling: function (n, elem) {
var r = [];
for (; n; n = n.nextSibling) {
if (n.nodeType === 1 && n !== elem) {
r.push(n);
}
}
return r;
}
});
jQuery.fn.extend({
has: function (target) {
var i,
targets = jQuery(target, this),
len = targets.length;
return this.filter(function () {
for (i = 0; i < len; i++) {
if (jQuery.contains(this, targets[i])) {
return true;
}
}
});
}
});
function sibling(cur, dir) {
do {
cur = cur[dir];
} while (cur && cur.nodeType !== 1);
return cur;
}
jQuery.each({
next: function (elem) {
return sibling(elem, "nextSibling");
},
prev: function (elem) {
return sibling(elem, "previousSibling");
}
siblings: function (elem) {
return jQuery.sibling((elem.parentNode || {}).firstChild, elem);
},
children: function (elem) {
return jQuery.sibling(elem.firstChild);
}
}, function (name, fn) {
jQuery.fn[name] = function (until, selector) {
var ret = jQuery.map(this, fn, until);
if (name.slice(-5) !== "Until") {
selector = until;
}
if (selector && typeof selector === "string") {
ret = jQuery.filter(selector, ret);
}
if (this.length > 1) {
// Remove duplicates
if (!guaranteedUnique[name]) {
ret = jQuery.unique(ret);
}
// Reverse order for parents* and prev-derivatives
if (rparentsprev.test(name)) {
ret = ret.reverse();
}
}
return this.pushStack(ret);
};
});
(function () {
var div = document.createElement("div");
// Execute the test only if not already executed in another module.
if (support.deleteExpando == null) {
// Support: IE<9
support.deleteExpando = true;
try {
delete div.test;
} catch (e) {
support.deleteExpando = false;
}
}
// Null elements to avoid leaks in IE.
div = null;
})();
/*
* Helper functions for managing events -- not part of the public interface.
* Props to Dean Edwards' addEvent library for many of the ideas.
*/
jQuery.event = {
global: {},
trigger: function (event, data, elem, onlyHandlers) {
var handle, ontype, cur,
bubbleType, special, tmp, i,
eventPath = [elem || document],
type = hasOwn.call(event, "type") ? event.type : event,
namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
cur = tmp = elem = elem || document;
// Don't do events on text and comment nodes
if (elem.nodeType === 3 || elem.nodeType === 8) {
return;
}
// focus/blur morphs to focusin/out; ensure we're not firing them right now
if (rfocusMorph.test(type + jQuery.event.triggered)) {
return;
}
if (type.indexOf(".") >= 0) {
// Namespaced trigger; create a regexp to match event type in handle()
namespaces = type.split(".");
type = namespaces.shift();
namespaces.sort();
}
ontype = type.indexOf(":") < 0 && "on" + type;
// Caller can pass in a jQuery.Event object, Object, or just an event type string
event = event[jQuery.expando] ?
event :
new jQuery.Event(type, typeof event === "object" && event);
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
event.isTrigger = onlyHandlers ? 2 : 3;
event.namespace = namespaces.join(".");
event.namespace_re = event.namespace ?
new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") :
null;
// Clean up the event in case it is being reused
event.result = undefined;
if (!event.target) {
event.target = elem;
}
// Clone any incoming data and prepend the event, creating the handler arg list
data = data == null ?
[event] :
jQuery.makeArray(data, [event]);
// Allow special events to draw outside the lines
special = jQuery.event.special[type] || {};
if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
return;
}
// Determine event propagation path in advance, per W3C events spec (#9951)
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
bubbleType = special.delegateType || type;
if (!rfocusMorph.test(bubbleType + type)) {
cur = cur.parentNode;
}
for (; cur; cur = cur.parentNode) {
eventPath.push(cur);
tmp = cur;
}
// Only add window if we got to document (e.g., not plain obj or detached DOM)
if (tmp === (elem.ownerDocument || document)) {
eventPath.push(tmp.defaultView || tmp.parentWindow || window);
}
}
// Fire handlers on the event path
i = 0;
while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
event.type = i > 1 ?
bubbleType :
special.bindType || type;
// jQuery handler
handle = (jQuery._data(cur, "events") || {})[event.type] && jQuery._data(cur, "handle");
if (handle) {
handle.apply(cur, data);
}
// Native handler
handle = ontype && cur[ontype];
if (handle && handle.apply && jQuery.acceptData(cur)) {
event.result = handle.apply(cur, data);
if (event.result === false) {
event.preventDefault();
}
}
}
event.type = type;
// If nobody prevented the default action, do it now
if (!onlyHandlers && !event.isDefaultPrevented()) {
if ((!special._default || special._default.apply(eventPath.pop(), data) === false) &&
jQuery.acceptData(elem)) {
// Call a native DOM method on the target with the same name name as the event.
// Can't use an .isFunction() check here because IE6/7 fails that test.
// Don't do default actions on window, that's where global variables be (#6170)
if (ontype && elem[type] && !jQuery.isWindow(elem)) {
// Don't re-trigger an onFOO event when we call its FOO() method
tmp = elem[ontype];
if (tmp) {
elem[ontype] = null;
}
// Prevent re-triggering of the same event, since we already bubbled it above
jQuery.event.triggered = type;
try {
elem[type]();
} catch (e) {
// IE<9 dies on focus/blur to hidden element (#1486,#12518)
// only reproducible on winXP IE8 native, not IE9 in IE8 mode
}
jQuery.event.triggered = undefined;
if (tmp) {
elem[ontype] = tmp;
}
}
}
}
return event.result;
},click: {
// For checkbox, fire native event so checked state will be right
trigger: function () {
if (jQuery.nodeName(this, "input") && this.type === "checkbox" && this.click) {
this.click();
return false;
}
},
// For cross-browser consistency, don't fire native .click() on links
_default: function (event) {
return jQuery.nodeName(event.target, "a");
}
}
}
jQuery.Event = function (src, props) {
// Allow instantiation without the 'new' keyword
if (!(this instanceof jQuery.Event)) {
return new jQuery.Event(src, props);
}
// Event object
if (src && src.type) {
this.originalEvent = src;
this.type = src.type;
// Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = src.defaultPrevented ||
src.defaultPrevented === undefined &&
// Support: IE < 9, Android < 4.0
src.returnValue === false ?
returnTrue :
returnFalse;
// Event type
} else {
this.type = src;
}
// Put explicitly provided properties onto the event object
if (props) {
jQuery.extend(this, props);
}
// Create a timestamp if incoming event doesn't have one
this.timeStamp = src && src.timeStamp || jQuery.now();
// Mark it as fixed
this[jQuery.expando] = true;
};
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
jQuery.Event.prototype = {
isDefaultPrevented: returnFalse,
isPropagationStopped: returnFalse,
isImmediatePropagationStopped: returnFalse,
preventDefault: function () {
var e = this.originalEvent;
this.isDefaultPrevented = returnTrue;
if (!e) {
return;
}
// If preventDefault exists, run it on the original event
if (e.preventDefault) {
e.preventDefault();
// Support: IE
// Otherwise set the returnValue property of the original event to false
} else {
e.returnValue = false;
}
},
stopPropagation: function () {
var e = this.originalEvent;
this.isPropagationStopped = returnTrue;
if (!e) {
return;
}
// If stopPropagation exists, run it on the original event
if (e.stopPropagation) {
e.stopPropagation();
}
// Support: IE
// Set the cancelBubble property of the original event to true
e.cancelBubble = true;
},
stopImmediatePropagation: function () {
var e = this.originalEvent;
this.isImmediatePropagationStopped = returnTrue;
if (e && e.stopImmediatePropagation) {
e.stopImmediatePropagation();
}
this.stopPropagation();
}
};
// Create mouseenter/leave events using mouseover/out and event-time checks
jQuery.each({
mouseenter: "mouseover",
mouseleave: "mouseout",
pointerenter: "pointerover",
pointerleave: "pointerout"
}, function (orig, fix) {
jQuery.event.special[orig] = {
delegateType: fix,
bindType: fix,
handle: function (event) {
var ret,
target = this,
related = event.relatedTarget,
handleObj = event.handleObj;
// For mousenter/leave call the handler if related is outside the target.
// NB: No relatedTarget if the mouse left/entered the browser window
if (!related || (related !== target && !jQuery.contains(target, related))) {
event.type = handleObj.origType;
ret = handleObj.handler.apply(this, arguments);
event.type = fix;
}
return ret;
}
};
});
jQuery.noConflict = function (deep) {
if (window.$ === jQuery) {
window.$ = _$;
}
if (deep && window.jQuery === jQuery) {
window.jQuery = _jQuery;
}
return jQuery;
};
// Expose jQuery and $ identifiers, even in
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
if (typeof noGlobal === strundefined) {
window.jQuery = window.$ = jQuery;
}
return jQuery;
}));
jquery의 확장 및 2차 개발
(function (window, $, undefined) {
var COOKIE_USER = "COOKIE_USER",
SERVICE_ROOT = "http://localhost:8000/",
SERVICE_PATH = SERVICE_ROOT + "/"
$.support.cors = true;
var jqueryAjax = $.ajax;
var _Core = function () {
var eventarr = [];
var _OnPageLoad = undefined;
/// USER
var getUser = function () {
//var obj = {};
//obj.USERID = $.cookie(COOKIE_USER);
var cookieData = $.cookie(COOKIE_USER);
if (cookieData === undefined) {
$Core.TimeOut();
return {};
}
var cookieuser;
try {
cookieuser = $.parseJSON(cookieData);
} catch (e) {
$Core.TimeOut();
//window.location.href = TIMEOUT_PATH;
return {};
}
if (cookieuser == undefined || cookieuser.USERID == undefined) {
//
//alert(" !");
$Core.TimeOut();
//window.location.href = TIMEOUT_PATH;
return {};
}
return cookieuser;
}
this.DEBUG = function () { return DEBUG; };
//
this.USER = function () {
return getUser();
};
//
this.SERVICEPATH = function () {
return SERVICE_PATH;
};
this.SERVICEROOT = function () {
return SERVICE_ROOT;
}
this.APPID = APP_ID;
this.ajax = jqueryAjax;
this.IsAjaxTimeOut = false;
var _loading = function () {
this.AjaxLoadingStart = function () {
$("#pageloadingright").fadeIn();
};
this.HideAjaxLoading = function () {
$("#pageloadingright").fadeOut(500);
};
this.HidePageLoading = function () {
$("#pageloading").fadeOut(500);
}
this.HideAll = function () {
this.HideAjaxLoading();
this.HidePageLoading();
}
};
this.Loading = new _loading();
/**
* ajax
* @param {function()} func
*/
this.OnPageLoad = function (func) {
if (func !== undefined)
_OnPageLoad = func;
};
var pageLoad = function () {
if (_OnPageLoad)
_OnPageLoad();
};
$(function () {
var _interval = setInterval(function () {
//if
if (!window.ajaxruning) {
clearInterval(_interval);
pageLoad();
}
}, 100);
});
};
window.$Core = new _Core();
var _UI = function () {
var _message = function () {
var createAlert = function (type, msg, timeout) {
if (timeout === undefined)
timeout = 2000;
var div = $(
'' +
'