jquery源码分析三 96-283行源码解析

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


constructor: jQuery,//重新定义prototype的constructor,防止被修改了
init: function( selector, context, rootjQuery ) {//forexample:$('li','ul')===$('ul li')
var match, elem;


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


// Handle HTML strings
/*处理字符串的,类似于$('这里面是字符串'),
 forexample : 
 1.$('#div'),$('.class'),$('div')等等,走下面if
 2.$('<div></div>')创建div,走下面else
*/
if ( typeof selector === "string" ) {
/*  2.$('<div></div>')创建div
   <开始>结束符合
*/
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 {
/* 1.$('#div'),$('.class'),$('div')等等,
理解下正则,不太难rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
?:\s*表示去掉空格,
(<[\w\W]+>)[^>]*|#([\w-]*):<[\w\W]+>)[^>]*表示匹配<开头>结束,中间字符 & #([\w-]*表示#开头后面跟字符.
forexample:$('<li>'),$('#id')这样match为true,
其他都为false,$('.class') $('div')都是false
跟上面的一起总结下:$('#div') 解析成 match = ['#div', null, 'div']
$('<li>aa') 解析成 match = ['<li>aa','<li>',null]
$('.class') $('tag') 解析成match = null;
正则可以单独自己去测试下,确实比较精妙
*/
match = rquickExpr.exec( selector );
}


// Match html or make sure no context is specified for #id
// 英文已经说的很清楚,上面也解释了,不说了. forexample : $('#id'),$('<li>')才能进入
if ( match && (match[1] || !context) ) {


// HANDLE: $(html) -> $(array)
if ( match[1] ) {//$(html)还用解释?forexample:$('<li>')下面也用$(html)替代这种方式,那肯定else是$('#id')的形式
context = context instanceof jQuery ? context[0] : context;//无论是不是jquery的写法,都返回原生js的document


// scripts is true for back-compat
/*
jQuery.parseHTML:把$('<li>1</li><li>2</li><li>3</li>')解析成['li','li','li']
jQuery.merge把this和jQuery.parseHTML后的数组合并成json,
合并成的格式:this的格式,console.log({0:'a',1:'b',length:2...}),随意log看下json对象,里面的属性都包括
jQuery.parseHTML和jQuery.merge两个实现放在后面函数的时候在详细讲
*/
jQuery.merge( this, jQuery.parseHTML(
match[1],
context && context.nodeType ? context.ownerDocument || context : document,
true
) );


// HANDLE: $(html, props)
/* Match a standalone tag
  rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,匹配单标签forexample:$('<li>')||$('<li></li>')为true,$('<li></li><li></li>')为false
  jQuery.isPlainObject( context ) object类型,相当于json格式
  $('<li>',{title:'hi',html:'abc',css:{background:'red'}})context值得是title,html,css
  jQuery.isFunction:函数默认是this.html(),this.css('background','red')
  title就this.attr('title','hi');
*/
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 ) {
// 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)
/*
 对dom节点进行处理
 forexample:$(this),$(document)
*/
} else if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;


// HANDLE: $(function)
// Shortcut for document ready
/*
 处理函数的
 $(function(){})
*/
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}


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


/*
处理数组或json等数据格式的
forexample:$([]),$({})等
*/
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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值