jquery内核及实现原理(二)--选择,迭代,命名空间,继承,参数
5)成熟--选择器
jquery返回的是一个类数组对象,也就是说有数组的长度和下标,但是没有数组的方法.
<div>11</div>
<div>22</div>
<div>33</div>
<div>44</div>
<div>55</div>
<script type="text/javascript">
var $ = jquery = function(selector,context){
return new jquery.fn.init(selector,context);
}
jquery.fn = jquery.protopyte = { //扩展原型对象
init : function(selector,context){
selector = selector || document; //如果第一个参数有值,则selector为参数值,否则为这个页面的document对象
context = context || document;
if(selector.nodeType){ //nodeType属性表示节点类型,如果是string类型的,则是undefined,其他比较重要的值为元素element为1,文档document为9等
this[0] = selector; //如果没传参数,则selector为document对象,selector.nodeType为9
this.length = 1;
this.context = selector;
return this;
}
if(typeof(selector) === "string"){ //如果传入的值是string类型的
var e = context.getElementsByTagName(selector); //获取传入值的所有节点
for(var i = 0;i< e.length;i++){
this[i]=e[i];
}
this.length = e.length;
this.context = context;
return this;
}else{
this.length = 0;
this.context = context;
return this;
}
},
length : "100",
jquery : "1.9.0",
size : function(){
return this.length;
}
}
jquery.fn.init.prototype = jquery.fn;
alert($("div").size()); //打印出来是5
</script>
上述代码基本有了框架中$("div")语法的功能,他可以选择指定范围的div元素,并且调用size()方法返回长度.
6)延伸--迭代器
jquery提供了一个each工具函数用来迭代,下面用html()方法来模拟迭代:
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<script type="text/javascript">
var $ = jquery = function(selector,context){
return new jquery.fn.init(selector,context);
}
jquery.fn = jquery.protopyte = { //扩展原型对象
init : function(selector,context){
selector = selector || document; //如果第一个参数有值,则selector为参数值,否则为这个页面的document对象
context = context || document;
if(selector.nodeType){ //nodeType属性表示节点类型,如果是string类型的,则是undefined,其他比较重要的值为元素element为1,文档document为9等
this[0] = selector; //如果没传参数,则selector为document对象,selector.nodeType为9
this.length = 1;
this.context = selector;
return this;
}
if(typeof(selector) === "string"){ //如果传入的值是string类型的
var e = context.getElementsByTagName(selector); //获取传入值的所有节点
for(var i = 0;i< e.length;i++){
this[i]=e[i];
}
this.length = e.length;
this.context = context;
return this;
}else{
this.length = 0;
this.context = context;
return this;
}
},
length : "100",
jquery : "1.9.0",
size : function(){
return this.length;
},
html : function(val){
jquery.each(this,function(val){
this.innerHTML = val;
},val);
}
}
jquery.fn.init.prototype = jquery.fn;
jquery.each = function(object,callback,args){
for(var i=0;i<object.length;i++){
callback.call(object[i],args);
}
return object;
}
$("div").html("test"); //每个div展示test
</script>
7延伸--功能扩展
jquery框架用extend()函数来快速扩展jquery的功能,这样做的好处是不会破坏jquery框架,方便管理,如果不需要某个插件,直接删除就可以了,而不必侵入jquery框架里面去筛选删除.
<body>
<div></div>
<script type="text/javascript">
var $ = jquery = function(selector,context){
return new jquery.fn.init(selector,context);
}
jquery.fn = jquery.protopyte = { //扩展原型对象
init : function(selector,context){
selector = selector || document;
context = context || document;
if(selector.nodeType){
this[0] = selector;
this.length = 1;
this.context = selector;
return this;
}
if(typeof(selector) == "string"){
var e = context.getElementsByTagName(selector);
for(var i = 0;i< e.length;i++){
this[i]=e[i];
}
this.length = e.length;
this.context = context;
return this;
}else{
this.length = 0;
this.context = context;
return this;
}
},
length : "3",
jquery : "1.9.0",
size : function(){
return this.length;
}
}
jquery.fn.init.prototype = jquery.fn;
jquery.extend = jquery.fn.extend = function(obj){
for(var prop in obj){
this[prop] = obj[prop];
}
return this;
}
jquery.fn.extend({
test : function(){
alert("这是测试方法");
}
})
$("div").test();
</script>
</body>当然jquery的extend方法要复杂很多,不仅能扩展,还能实现对象合并等方法.
8延续--参数处理
jquery在extend()里处理参数,里面定义了一个options,有初始值,如果外界传过来的值在里面有定义,就覆盖,否则就多加一个参数.
9涅槃--名字空间
jquery用闭包的方式来避免名称和其他框架冲突,也防止了其他框架调用jquery方法,具体做法是:
(function(){
})()
因为$并不是jquery的专利,其他框架也会用到这个变量,所以jquery用noConflict(jquery1.9.0里的方法,其他版本可能是noConfilit())方法来避免:
noConflict: function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
}使用的时候要写成例如jQuery("div").test()