JQuery最重要的作用就是查询DOM节点,比浏览器原生的查询方式更加优雅,比如html中的一张图片:
<img src="bar.jpg" id="img"/>
两种查询方式比较:
//原生接口
var image = document.getElementById('img');
//JQuery 方法
var jqImgae = $('#img');
jQuery 与 jQuery.fn
在JQuery源码中,JQuery()的实现方式:
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context, rootjQuery );
}
可以看到内部返回了一个jQuery.fn.init对象,用这种方式创建DOM对象的好处是隐藏了new的过程,使用 jQuery(‘#id’) 创建对象更加简洁,而不是 new jQuery(‘#id’) 。
jQuery.fn.init()函数实际是封装了查询DOM节点的原生接口,下面是init()的简洁版实现,JQuery中的实现复杂的多,还要考虑浏览器兼容性问题。
jQuery.fn = jQuery.prototype = {
init: function(selector, context){
var nodeList = (context || document).querySelectorAll(selector);
this.length = nodeList.length;
for (var i=0; i<this.length; i+=1) {
this[i] = nodeList[i];
}
return this;
},
each:function(){...}
...
}
可以看到init()函数中将DOM节点赋值给了自己this[i] = nodeList[i],因此返回的init对象是一个类数组,包含了DOM节点列表,还包括一些其他的方法。
其中 jQuery.fn = jQuery.prototype 则可以隐藏prototype属性,在后面为jQuery添加新方法时可以使用
jQuery.fn.each = function(){...}
jQuery.fn.map = function(){...}
但是new jQuery.fn.init()中返回this,即init对象,此时init对象上并没有添加任何方法,于是:
jQuery.fn.init.prototype = jQuery.fn;
这样init对象继承了jQuery.fn中的所有方法,就可以愉快地使用了。
jQuery.extend
jQuery中还使用了大量extend({…})
jQuery.extend = jQuery.fn.extend = function(){..}
该函数主要目的是简化添加扩展函数的过程:
例如:
jQuery.fn.each = function(){...}
jQuery.fn.map = function(){...}
jQuery.fn.css = function(){...}
可以简化为
jQuery.fn.extend({
each:function(){...},
map:function(){...},
css:function(){...},
})
而jQuery.extend 和 jQuery.fn.extend区别像是一个静态函数,一个实例函数,前者使用方法为:
jQuery.extend({
isWindow: function( obj ) {
return obj != null && obj == obj.window;
}
})
jQuery.isWindow(window) //true
而后者
jQuery.fn.extend({
addClass: function() {...}
})
jQuery('#img').addClass('small')