发一下牢骚和主题无关:
一、源码思绪析分结总
[ 作者:华子yjh ]
要概:
jQuery的核心想思可以简略归纳综合为“查询和操纵dom”,明天主要是析分一下jQuery.prototype.init选择器构造函数,处置选择器函数中的参数;
这个函数的参数就是jQuery()===$()执行函数中的参数,可以先看我之前写的浅析jQuery础基框架一文,懂得础基框架后,再看此文。
思绪析分:
以下是几种jQuery的使用况情(于用查询dom),每种况情都返回一个选择器例实(习惯称jQuery对象(一个nodeList对象),该对象含包查询的dom点节):
1、处置 $(""), $(null), $(undefined), $(false)
如果参数为以上法非值,jQuery对象不含包dom点节
2、处置 $(DOMElement)
如果参数为点节元素,jQuery对象含包该参数点节元素,并别分增长属性值为参数点节元素、1的context、length属性和用[]拜访jQuery对象中dom点节的用法
例2.1:
1 var obj = document.getElementById('container'), 2 jq = $(obj); 3 4 console.log(jq.length); //1 5 console.log(jq.context); //obj 6 console.log(jq.[0]); //obj
3、处置$(HTML字符串)
如果第一个参数为HTML字符串,jQuery对象含包由jQuery.clean函数创立的fragment档文碎片中的childnodes点节
例3.1:
1 var jqHTML = $('<h1>文章题标</h1><p>内容</p>'); 2 console.log(jqHTML); //[<h1>,<p>];
例3.2:
1 var jqHTML = $('<div></div>', { class: 'css-class', data-name: 'data-val' }); 2 3 console.log(jqHTML.attr['class']); //css-class 4 console.log(jqHTML.attr['data-name']); //data-val
4、处置$(#id)
如果第一个参数是一个#加元素id,jQuery对象含包独一有拥该id的元素点节,
并别分增长属性值为document、参数字符串、1、的context、selector、length属性和用[]拜访jQuery对象中dom点节的用法
例4.1:
1 var jq = $('#container'); 2 3 console.log(jq.[0]); //含包的dom点节元素 4 console.log(jq.length); //1 5 console.log(jq.context); //document 6 console.log(jq.selector); //container
5、处置$(.className)
如果第一个参数是一个.className,jQuery对象中有拥class名为className的标签元素,并增长一个属性值为参数字符串、document的selector、context属性
现实执行代码为:
1 return jQuery(document).find(className);
6、处置$(.className, context)
如果第一个参数是.className,第二个参数是一个上下文对象(可是以.className(等同于处置$(.className .className)),jQuery对象或dom点节),
jQuery对象含包第二个参数上下文对象中有拥class名为className的后代点节元素,并增长一个context和selector属性
现实执行代码为:
1 return jQuery(context).find(className);
html代码:
1 <div class="main"> 2 <h2 class="title">主内容题标</h2> 3 <p>主题标</p> 4 </div> 5 6 <div class="sub"> 7 <h2 class="title">次内容题标</h2> 8 <p>次题标</p> 9 </div>
1 var jq, context; 2 3 context = '.sub'; 4 var jq = $('.title', context); 5 console.log(jq.text()); //次内容题标 6 console.log(jq.context); //document 7 console.log(jq.selector); //.sub .title 8 9 context = $('.sub'); 10 var jq = $('.title', context); 11 console.log(jq.text()); //次内容题标 12 console.log(jq.context); //document 13 console.log(jq.selector); //.sub .title 14 15 context = $('.sub')[0]; 16 var jq = $('.title', context); 17 console.log(jq.text()); //次内容题标 18 console.log(jq.context); //className为sub的点节元素 19 console.log(jq.selector); //.title
7、处置$(fn)
如果第一个参数是fn函数,则调用$(document).ready(fn);
例7.1:
1 $(function(e){ 2 console.log('DOMContent is loaded'); 3 }) 4 //面上代码等同于: 5 jQuery(document).ready(function(e) { 6 console.log('DOMContent is loaded'); 7 });
8、处置$(jQuery对象)
如果第一个参数是jQuery对象,面上经已析分过如果在查询dom时,参数是一个#加元素id,返回的jQuery对象会增长一个属性值为参数字符串、document的selector、context属性
例8.1:
1 var jq = $('#container'); 2 console.log(jq.selector); // #container 3 console.log(jq.context); // document
例8.2:
1 var jq2 = $($('#container')); 2 console.log(jq2.selector); // #container 3 console.log(jq2.context); // document
二、源码释注析分
[ 基于jQuery1.8.3 ]
1 var rootjQuery = $(document), 2 rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/; 3 4 jQuery.fn = jQuery.prototype = { 5 init: function( selector, context, rootjQuery ) { 6 var match, elem, ret, doc; 7 8 // Handle $(""), $(null), $(undefined), $(false) 9 if ( !selector ) { 10 return this; 11 } 12 13 // Handle $(DOMElement) 14 if ( selector.nodeType ) { 15 this.context = this[0] = selector; 16 this.length = 1; 17 return this; 18 } 19 20 // Handle HTML strings 21 if ( typeof selector === "string" ) { 22 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { 23 // Assume that strings that start and end with <> are HTML and skip the regex check 24 match = [ null, selector, null ]; 25 26 } else { 27 match = rquickExpr.exec( selector ); 28 } 29 30 // Match html or make sure no context is specified for #id 31 // match[1]不为null,则为html字符串,match[2]不为null,则为元素id 32 if ( match && (match[1] || !context) ) { 33 34 // HANDLE: $(html) -> $(array) 35 if ( match[1] ) { 36 context = context instanceof jQuery ? context[0] : context; 37 doc = ( context && context.nodeType ? context.ownerDocument || context : document ); 38 39 // scripts is true for back-compat 40 // selector是由档文碎片中的childnodes构成的组数 41 selector = jQuery.parseHTML( match[1], doc, true ); 42 43 // 如果match[1]为空的单标签元素(如:<div><div>)且context为对象字面量 44 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { 45 46 // 如果context对象不为空,则将对象中的属性添加到selector组数中有仅的dom点节中 47 this.attr.call( selector, context, true ); 48 } 49 50 // merge函数的参数应该为两个组数,的目是将第二个组数中的项合并到第一个组数,而this并非一个组数, 51 // this是选择器init构造函数的例实对象,该对象继承jQuery.prototype对象中的length属性(默为认0),因此可以解理好merge函数源码 52 // 将selector中的dom项合并到this对象中,并返回该对象 53 return jQuery.merge( this, selector ); 54 55 // HANDLE: $(#id) 56 } else { 57 elem = document.getElementById( match[2] ); 58 59 // Check parentNode to catch when Blackberry 4.6 returns 60 // nodes that are no longer in the document #6963 61 if ( elem && elem.parentNode ) { 62 // Handle the case where IE and Opera return items 63 // by name instead of ID 64 // ie6,7和Opera存在此bug,当一个标签name和一个标签id值相等时, 65 // document.getElementById(#id)函数将返回前提涌现的标签元素 66 if ( elem.id !== match[2] ) { 67 // 如果存在以上Bug,则返回由find函数返回的document档文的后代元素集合 68 return rootjQuery.find( selector ); 69 } 70 71 // Otherwise, we inject the element directly into the jQuery object 72 this.length = 1; 73 this[0] = elem; 74 } 75 76 this.context = document; 77 this.selector = selector; 78 return this; 79 } 80 81 // HANDLE: $(expr, $(...)) 82 // context不存在或者context为jQuery对象 83 } else if ( !context || context.jquery ) { 84 return ( context || rootjQuery ).find( selector ); 85 86 // HANDLE: $(expr, context) 87 // (which is just equivalent to: $(context).find(expr) 88 // context为className或者dom点节元素 89 } else { 90 // 等同于jQuery(context).find(selector) 91 return this.constructor( context ).find( selector ); 92 } 93 94 // 处置$(fn)===$(document).ready(fn) 95 } else if ( jQuery.isFunction( selector ) ) { 96 return rootjQuery.ready( selector ); 97 } 98 99 // 处置$(jQuery对象) 100 if ( selector.selector !== undefined ) { 101 this.selector = selector.selector; 102 this.context = selector.context; 103 } 104 105 // 当第一个参数selector为jQuery对象时,将selector中的dom点节合并到this对象中,并返回this对象 106 return jQuery.makeArray( selector, this ); 107 } 108 }
文章结束给大家分享下程序员的一些笑话语录: 有一天,一个男人穿越森林的时候,听到一个细微的声音叫住他。他低头一看,是一只青蛙。
“如果你亲我一下,我会变成一个美丽的公主哦。”男人一言不发,把青蛙捡起来,放入口袋。
“如果你亲我一下,我会变成一个美丽的公主哦。而且,我会告诉我遇到的每一个人,你是多么聪明和勇敢,你是我的英雄。”男人把青蛙拿出来,对着它微微一笑,又把它放回口袋。
“如果你亲我一下,我会变成一个美丽的公主,然后我愿意成为你的爱人一星期。”男人又把青蛙拿出来,对着它微微一笑,把它放回口袋。
“如果你亲我一下,我会变成一个美丽的公主,然后我愿意成为你的爱人一年,而且你可以对我做任何事。”再一次,男人把青蛙拿出来,对着它微微一笑,又把它放回口袋。
最后,青蛙无力地问:“我开出了这么好的条件,为什么你还不肯吻我?”男人说:“我是一个程序员,我可没时间和什么公主鬼混。不过,拥有一个会说话的青蛙,倒是蛮酷的。”