您的位置:首页 > Web前端 > JQuery

JQuery 1.10.2源码分析学习2

2013-09-02 14:44 417 查看
一样先上源码

jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
jquery: core_version,

constructor: jQuery,
init: function( selector, context, rootjQuery ) {
var match, elem;

// HANDLE: $(""), $(null), $(undefined), $(false)
if ( !selector ) {
return this;
}

// Handle HTML strings
if ( typeof selector === "string" ) {
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];

} else {
match = rquickExpr.exec( selector );
}

// Match html or make sure no context is specified for #id
if ( match && (match[1] || !context) ) {

// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;

// scripts is true for back-compat
jQuery.merge( this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
) );

// HANDLE: $(html, props)
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
for ( match in context ) {
// Properties of context are called as methods if possible
if ( jQuery.isFunction( this[ match ] ) ) {
this[ match ]( context[ match ] );

// ...and otherwise set as attributes
} else {
this.attr( match, context[ match ] );
}
}
}

return this;

// HANDLE: $(#id)
} else {
elem = document.getElementById( match[2] );

// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}

// Otherwise, we inject the element directly into the jQuery object
this.length = 1;
this[0] = elem;
}

this.context = document;
this.selector = selector;
return this;
}

// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
return ( context || rootjQuery ).find( selector );

// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor( context ).find( selector );
}

// HANDLE: $(DOMElement)
} else if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;

// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}

if ( selector.selector !== undefined ) {
this.selector = selector.selector;
this.context = selector.context;
}

return jQuery.makeArray( selector, this );
},

// Start with an empty selector
selector: "",

// The default length of a jQuery object is 0
length: 0,

toArray: function() {
return core_slice.call( this );
},

// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
get: function( num ) {
return num == null ?

// Return a 'clean' array
this.toArray() :

// Return just the object
( num < 0 ? this[ this.length + num ] : this[ num ] );
},

// Take an array of elements and push it onto the stack
// (returning the new matched element set)
pushStack: function( elems ) {

// Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems );

// Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context;

// Return the newly-formed element set
return ret;
},

// Execute a callback for every element in the matched set.
// (You can seed the arguments with an array of args, but this is
// only used internally.)
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},

ready: function( fn ) {
// Add the callback
jQuery.ready.promise().done( fn );

return this;
},

slice: function() {
return this.pushStack( core_slice.apply( this, arguments ) );
},

first: function() {
return this.eq( 0 );
},

last: function() {
return this.eq( -1 );
},

eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
},

map: function( callback ) {
return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
},

end: function() {
return this.prevObject || this.constructor(null);
},

// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: core_push,
sort: [].sort,
splice: [].splice
};

// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;


我们先看上面源码中的最后一句 jQuery.fn.init.prototype = jQuery.fn;

上篇我说过了,这样做就实现了JQuery.fn.init的prototype指向了jQuery.fn的prototype,这样实现了链式编程的操作。

下面我们一个一个来看这个函数里做了什么。

首先是init这个函数

selector有以下7种分支情况:

DOM元素

body(优化)

字符串:HTML标签、HTML字符串、#id、选择器表达式

函数(作为ready回调函数)

最后返回伪数组

toArray:把JQuery集合中所有DOM元素恢复成一个数组

pushStack:取一个数组中的元素,将其放入堆上,返回新的堆上的元素集合(jQuery对象)

end:大多数
jQuery 的遍历方法会操作一个 jQuery 对象实例,并生成一个匹配不同 DOM 元素集的新对象。当发生这种情况时,应该会把新的元素集推入维持在对象中的堆栈内。每次成功的筛选方法调用都会把新元素推入堆栈中。如果我们需要老的元素集,可以使用 end() 从堆栈中弹出新集合。

get:说到get需要把它和eq一起来说 eq返回的是一个jquery对象(这个用了pushStack),get返回的是一个html
对象数组(这个用了toArray)。

each:为每个匹配到的元素规定运行的函数。

ready:当页面加载完在一一运行函数。

frist:选取匹配好的元素集合中的第一个元素。

last:选取匹配好的元素集合中的最后一个元素。

map: 把每个元素通过函数传递到当前匹配集合中,生成包含返回值的新的
jQuery 对象。

下一章准备我对上面的方法做一些详细的解释和对比,包括他们的用法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: