🔹 제이쿼리 동작원리
function jQuery(a,c) {
// Shortcut for document ready (because $(document).each() is silly)
if ( a && a.constructor == Function && jQuery.fn.ready )
return jQuery(document).ready(a); // (1)
// Make sure that a selection was provided
a = a || jQuery.context || document; // (2)
// Watch for when a jQuery object is passed as the selector
if ( a.jquery )
return $( jQuery.merge( a, [] ) ); // (3)
// Watch for when a jQuery object is passed at the context
if ( c && c.jquery )
return $( c ).find(a); // (4)
// If the context is global, return a new object
if ( window == this )
return new jQuery(a,c); // (5)
// Handle HTML strings
var m = /^[^<]*(<.+>)[^>]*$/.exec(a);
if ( m ) a = jQuery.clean( [ m[1] ] ); // (6)
// Watch for when an array is passed in
this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ?
// Assume that it is an array of DOM Elements
jQuery.merge( a, [] ) :
// Find the matching elements and save them for later
jQuery.find( a, c ) ); // (7)
// See if an extra function was provided
var fn = arguments[ arguments.length - 1 ]; // (8)
// If so, execute it in context
if ( fn && fn.constructor == Function ) // (9)
this.each(fn);
}
// Map over the $ in case of overwrite
if ( typeof $ != "undefined" )
jQuery._$ = $;
// Map the jQuery namespace to the '$' one
var $ = jQuery;
🔹 jQuery의 prototype을 정의해둔 코드
jQuery.fn = jQuery.prototype = {
jquery: "$Rev: 509 $",
...,
get: function( num ) {
// Watch for when an array (of elements) is passed in
if ( num && num.constructor == Array ) {
// Use a tricky hack to make the jQuery object
// look and feel like an array
this.length = 0;
[].push.apply( this, num );
return this;
} else
return num == undefined ?
// Return a 'clean' array
jQuery.map( this, function(a){ return a } ) :
// Return just the object
this[num];
},
...,
find: function(t) {
return this.pushStack( jQuery.map( this, function(a){
return jQuery.find(t,a);
}), arguments );
},
...,
pushStack: function(a,args) {
var fn = args && args[args.length-1];
if ( !fn || fn.constructor != Function ) {
if ( !this.stack ) this.stack = [];
this.stack.push( this.get() );
this.get( a );
} else {
var old = this.get();
this.get( a );
if ( fn.constructor == Function )
return this.each( fn );
this.get( old );
}
return this;
}
}
🔹 jQuery.extend라고 숨겨진 코드
jQuery.extend = jQuery.fn.extend = function(obj,prop) {
if ( !prop ) { prop = obj; obj = this; }
for ( var i in prop ) obj[i] = prop[i];
return obj;
};
jQuery.extend({
...
find: function( t, context ) {
// Make sure that the context is a DOM Element
if ( context && context.nodeType == undefined ) // (1)
context = null;
// Set the correct context (if none is provided)
context = context || jQuery.context || document; // (2)
if ( t.constructor != String ) return [t]; // (3)
if ( !t.indexOf("//") ) { // (4)
context = context.documentElement;
t = t.substr(2,t.length);
} else if ( !t.indexOf("/") ) {
context = context.documentElement;
t = t.substr(1,t.length);
// FIX Assume the root element is right :(
if ( t.indexOf("/") >= 1 )
t = t.substr(t.indexOf("/"),t.length);
}
}
var ret = [context];
var done = [];
var last = null;
while ( t.length > 0 && last != t ) { // (5)
var r = [];
last = t;
t = jQuery.trim(t).replace( /^\/\//i, "" ); // (6)
var foundToken = false;
for ( var i = 0; i < jQuery.token.length; i += 2 ) { // (7)
if ( foundToken ) continue;
var re = new RegExp("^(" + jQuery.token[i] + ")");
var m = re.exec(t);
if ( m ) {
r = ret = jQuery.map( ret, jQuery.token[i+1] );
t = jQuery.trim( t.replace( re, "" ) );
foundToken = true;
}
}
if ( !foundToken ) { // (8)
if ( !t.indexOf(",") || !t.indexOf("|") ) { // (9)
if ( ret[0] == context ) ret.shift();
done = jQuery.merge( done, ret );
r = ret = [context];
t = " " + t.substr(1,t.length);
} else { // (10)
var re2 = /^([#.]?)([a-z0-9\\*_-]*)/i;
var m = re2.exec(t); // (11)
if ( m[1] == "#" ) { // (12)
// Ummm, should make this work in all XML docs
var oid = document.getElementById(m[2]); // (13)
r = ret = oid ? [oid] : [];
t = t.replace( re2, "" );
} else {
if ( !m[2] || m[1] == "." ) m[2] = "*";
for ( var i = 0; i < ret.length; i++ )
r = jQuery.merge( r,
m[2] == "*" ?
jQuery.getAll(ret[i]) :
ret[i].getElementsByTagName(m[2])
);
}
}
}
if ( t ) { // (14)
var val = jQuery.filter(t,r);
ret = r = val.r;
t = jQuery.trim(val.t);
}
}
if ( ret && ret[0] == context ) ret.shift(); // (15)
done = jQuery.merge( done, ret ); // (16)
return done;
},