jQuery源码学习笔记三(转)
2009-11-22 16:09
489 查看
还有一点,jQuery.prototype第一个阶级的能力部署就完成了。就像一个茧,jQuery对象包裹着一个或复数个DOM对象,jQuery对象的能力来自其prototype,而其prototype的方法则是jQuery.prototype的一个副本。
至此,jQuery对象第一阶级的能力就告一段落,要不对象体就很长。下面添加新的能力时就用jQuery.extend求添加,就像Prototype的Object.extend,mootool的Native.implement,Base2的Base.extend,Ext的apply,凡此种种,把一个属性包或独立的方法名与方法体作为参数加入目标对象中。因为光是在对象体搞(这里是原型),没有私有变量可言,有时我们很需要这些作为胶水在连接我们的方法,因此打散写有打散写的好处。更何况,jQuery类库都是整个包围在一个闭包中,这些散乱的函数与变量不会逃逸到外面去,与我们的业务逻辑中用的函数或变量发生命名冲突。
定义几个位于闭包的顶层变量,准备新一轮的功能扩展
接着下来就是对样式的操作了,样式在WEB开发中非常重要,我留在下一节重点讲!
转自:http://www.cnblogs.com/rubylouvre/
01.
//对当前jQuery中的DOM进行slice操作,并把参数传入this.prevObject中
02.
slice:
function
(){
03.
return
this
.pushStack(Array.prototype.slice.apply(
this
,arguments),
04.
"slice"
,Array.prototype.slice.call(arguments).join(
","
));
05.
},
06.
//与上面差不多
07.
map:
function
(callback){
08.
return
this
.pushStack(jQuery.map(
this
,
function
(elem,i){
09.
return
callback.call(elem,i,elem);
10.
}));
11.
},
12.
//把之前放入this.preveObject的DOM数组取出来,加入现在的DOM数组中
13.
andSelf:
function
(){
14.
return
this
.add(
this
.prevObject);
15.
},
16.
17.
domManip:
function
(args,table,callback){
18.
if
(
this
[0]){
19.
//如果jQuery对象有DOM元素,则取得其文档对象,调用其createDocumentFragment方法
20.
var
fragment=(
this
[0].ownerDocument||
this
[0]).createDocumentFragment(),
21.
//这里的args恒为arguments对象,用jQuery.clean获得纯DOM元素数组
22.
scripts=jQuery.clean(args,(
this
[0].ownerDocument||
this
[0]),fragment),
23.
first=fragment.firstChild;
24.
25.
if
(first)
26.
for
(
var
i=0,l=
this
.length;i<l;i++)
27.
//callback传入一个元素与一个文档
28.
callback.call(root(
this
[i],first),
this
.length>1||i>0?
29.
fragment.cloneNode(
true
):fragment);
30.
if
(scripts)
31.
jQuery.each(scripts,evalScript);
32.
}
33.
34.
return
this
;
35.
//root用于检测当前元素是否为table,是就检测tbody是否存在,没有则创建
36.
function
root(elem,cur){
37.
return
table&&jQuery.nodeName(elem,
"table"
)&&jQuery.nodeName(cur,
"tr"
)?
38.
(elem.getElementsByTagName(
"tbody"
)[0]||
39.
elem.appendChild(elem.ownerDocument.createElement(
"tbody"
))):
40.
elem;
41.
}
42.
}
43.
};
44.
//把jQuery.prototype的能力加持到jQuery.prototype.init.prototype上
45.
jQuery.fn.init.prototype=jQuery.fn;
至此,jQuery对象第一阶级的能力就告一段落,要不对象体就很长。下面添加新的能力时就用jQuery.extend求添加,就像Prototype的Object.extend,mootool的Native.implement,Base2的Base.extend,Ext的apply,凡此种种,把一个属性包或独立的方法名与方法体作为参数加入目标对象中。因为光是在对象体搞(这里是原型),没有私有变量可言,有时我们很需要这些作为胶水在连接我们的方法,因此打散写有打散写的好处。更何况,jQuery类库都是整个包围在一个闭包中,这些散乱的函数与变量不会逃逸到外面去,与我们的业务逻辑中用的函数或变量发生命名冲突。
01.
//jQuery的能力扩展的核心函数
02.
//这要求存在继承者与授与者两方,一般来说继承者在左,授与者在右,授与者通常是一个简单的属性包
03.
jQuery.extend=jQuery.fn.extend=
function
(){
04.
//copyreferencetotargetobject
05.
var
target=arguments[0]||{},i=1,length=arguments.length,deep=
false
,options;
06.
//Handleadeepcopysituation
07.
if
(
typeof
target===
"boolean"
){
//如果第一个参数是布尔值
08.
deep=target;
09.
target=arguments[1]||{};
//设置继承者
10.
//skipthebooleanandthetarget
11.
i=2;
12.
}
13.
//Handlecasewhentargetisastringorsomething(possibleindeepcopy)
14.
if
(
typeof
target!==
"object"
&&!jQuery.isFunction(target))
15.
target={};
16.
//如果没有指定要继承能力的对象,则扩展到自身
17.
//extendjQueryitselfifonlyoneargumentispassed
18.
if
(length==i){
19.
target=
this
;
20.
--i;
21.
}
22.
for
(;i<length;i++)
23.
//Onlydealwithnon-null/undefinedvalues
24.
if
((options=arguments[i])!=
null
)
25.
//Extendthebaseobject
26.
for
(
var
name
in
options){
27.
var
src=target[name],copy=options[name];
28.
29.
//Preventnever-endingloop
30.
if
(target===copy)
31.
continue
;
32.
//如果是深复制,某对象的属性也是对象并且不是HTMLElement,则把它逐一分解拷到继承者
33.
//Recurseifwe'remergingobjectvalues
34.
if
(deep&©&&
typeof
copy===
"object"
&&!copy.nodeType)
35.
target[name]=jQuery.extend(deep,
36.
//Nevermoveoriginalobjects,clonethem
37.
src||(copy.length!=
null
?[]:{})
38.
,copy);
39.
//Don'tbringinundefinedvalues
40.
else
if
(copy!==undefined)
41.
target[name]=copy;
42.
}
43.
//Returnthemodifiedobject
44.
return
target;
45.
};
定义几个位于闭包的顶层变量,准备新一轮的功能扩展
1.
//excludethefollowingcsspropertiestoaddpx
2.
//将转换成px单位
3.
var
exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,
4.
//cachedefaultView
5.
defaultView=document.defaultView||{},
6.
toString=Object.prototype.toString;
001.
//第二轮能力扩展,这次是添加一系列静态方法
002.
jQuery.extend({
003.
004.
noConflict:
function
(deep){
005.
//引入jQuery类库后,闭包外面的window.$与window.jQuery都储存着一个函数,
006.
//它是用来生成jQuery对象或在domReady后执行里面的函数的
007.
//回顾最上面的代码,在还没有把function赋给它们时,_jQuery与_$已经被赋值了,
008.
//因此它们俩的值一定必然是undefined
009.
//因此这种放弃控制权的技术很简单,就是用undefined把window.$里面的jQuery系的函数清除掉
010.
//这时Prototype或mootools的$就可以明门正娶了
011.
window.$=_$;
//相当window.$=undefined
012.
//如果连你的程序也有一个叫jQuery的东西呢,jQuery可以大方地连这个也让渡出去
013.
//这时就要为noConflict添加一个布尔值,为true
014.
if
(deep)
015.
//但我们必须用一个东西要接纳jQuery对象与jQuery的入口函数
016.
//闭包里面的东西除非被window等宿主对象引用,否则就是不可见的
017.
//因此我们把闭包里面的jQueryreturn出去,外面用一个变量接纳就是
018.
window.jQuery=_jQuery;
//相当window.jQuery=undefined
019.
return
jQuery;
020.
},
021.
022.
//外国近年来新发现的检测技术toString
023.
isFunction:
function
(obj){
024.
return
toString.call(obj)===
"[objectFunction]"
;
025.
},
026.
027.
isArray:
function
(obj){
028.
return
toString.call(obj)===
"[objectArray]"
;
029.
},
030.
031.
//checkifanelementisina(orisan)XMLdocument
032.
//检测是否为XML的文档对象
033.
isXMLDoc:
function
(elem){
034.
return
elem.nodeType===9&&elem.documentElement.nodeName!==
"HTML"
||
035.
!!elem.ownerDocument&&jQuery.isXMLDoc(elem.ownerDocument);
036.
},
037.
038.
//Evalulatesascriptinaglobalcontext
039.
//把一段文本解析成脚本,利用script元素的text属性
040.
globalEval:
function
(data){
041.
if
(data&&/\S/.test(data)){
042.
//InspiredbycodebyAndreaGiammarchi
043.
//http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
044.
var
head=document.getElementsByTagName(
"head"
)[0]||document.documentElement,
045.
script=document.createElement(
"script"
);
046.
//自行创建一个script元素,如果支持text属性则直接赋,不支持就用标准方法在里面添加文本
047.
script.type=
"text/javascript"
;
048.
if
(jQuery.support.scriptEval)
049.
script.appendChild(document.createTextNode(data));
050.
else
051.
script.text=data;
052.
//UseinsertBeforeinsteadofappendChildtocircumventanIE6bug.
053.
//Thisariseswhenabasenodeisused(#2709).
054.
head.insertBefore(script,head.firstChild);
055.
head.removeChild(script);
056.
}
057.
},
058.
//检测elem的nodeName是否等于第二个参数name
059.
nodeName:
function
(elem,name){
060.
return
elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();
061.
},
062.
//argsisforinternalusageonly
063.
each:
function
(object,callback,args){
064.
var
name,i=0,length=object.length;
065.
066.
if
(args){
067.
if
(length===undefined){
068.
//如果是对象就对其值调用方法,如果调用函数没有返回值或返回false就跳出循环
069.
for
(name
in
object)
070.
if
(callback.apply(object[name],args)===
false
)
071.
break
;
072.
}
else
073.
//如果是数组
074.
for
(;i<length;)
075.
if
(callback.apply(object[i++],args)===
false
)
076.
break
;
077.
//同上,只不过没有传入第三个参数
078.
//Aspecial,fast,caseforthemostcommonuseofeach
079.
}
else
{
080.
if
(length===undefined){
081.
for
(name
in
object)
082.
if
(callback.call(object[name],name,object[name])===
false
)
083.
break
;
084.
}
else
085.
for
(
var
value=object[0];
086.
i<length&&callback.call(value,i,value)!==
false
;value=object[++i]){}
087.
}
088.
089.
return
object;
090.
},
091.
//用于返回各种属性
092.
prop:
function
(elem,value,type,i,name){
093.
//Handleexecutablefunctions
094.
if
(jQuery.isFunction(value))
095.
value=value.call(elem,i);
096.
097.
//HandlepassinginanumbertoaCSSproperty
098.
return
typeof
value===
"number"
&&type==
"curCSS"
&&!exclude.test(name)?
099.
value+
"px"
:
100.
value;
101.
},
接着下来就是对样式的操作了,样式在WEB开发中非常重要,我留在下一节重点讲!
转自:
相关文章推荐
- jQuery源码研究分析学习笔记-回调函数(11)
- jquery源码学习笔记1
- jQuery源码研究分析学习笔记-jQuery.deferred()(12)
- jquery 2.0.3 源码学习笔记(三)类数组
- jQuery源码研究分析学习笔记-jQuery.extend()、jQuery.fn.extend()(八)
- jQuery源码研究分析学习笔记-静态方法和属性(10)
- jquery源码学习笔记
- 2016年11月2日——jQuery源码学习笔记
- jQuery源码学习笔记(05)
- jQuery源码学习笔记(09)
- jQuery源码学习笔记:构造jQuery对象
- jQuery源码研究分析学习笔记-jQuery.fn.init()(五)
- jQuery源码学习笔记一(转)
- 2016年11月1日——jQuery源码学习笔记
- 菜鸟的jQuery源码学习笔记(一)
- jquery源码学习笔记三:jQuery工厂剖析
- jQuery源码学习笔记一
- jQuery源码研究分析学习笔记-jQuery.buildFragment()(六)
- jquery 2.0.3 源码学习笔记(三)构造器
- jQuery源码学习笔记:jQuery.fn.init(selector,context,rootjQuery)代码详解