深入了解jquery(2)-扩展jquery以及实现链式调用
链式调用
jquery的链式调用非常让人愉悦, 简简单单几句话就能做很多事情. 正如它的口号, write less do more. 我们先来看看如何实现链式调用. 先看看我们自己的jquery版本.
(function () {
var jquery = window.jquery = $ = window.$ = function (selector, context) {return new jquery.fn.init(selector, context);}$.prototype = jquery.fn = jquery.prototype = {init: function (selector, context) {
if (selector.nodeType == 1) {
this[0] = selector;
this.length = 1;
return this;}}, css: function (cssjson) {
for (var i = 0; i < this.length; i++) {for (var stylename in cssjson) {this[i].style[stylename] = cssjson[stylename];
}}return this;}}jquery.prototype.init.prototype = $.prototype;})();我们现在的selector只能支持具体的dom节点. 现在假如页面上有一个id是div的元素. 我们可以用$(document.getElementById(‘div’))得到jquery对象. 经过上个帖子的分析. 我们知道这个jquery对象是jquery.fn.prototype.init函数类的实例. 这个对象通过jquery.prototype.init.prototype = $.prototype获得了jquery.prototype的所有成员. 因此jquery有了css方法.
下面我们来看看$(document.getElementById(‘div’)).css({color:’red’})这句话. 这里调用了css方法. 进入到css方法内, 方法内的this就是$(document.getElementById(‘div’)),(如果你还对this不是那么熟悉, 那么谷歌之补补课). 那么返回这个this. 就可以继续使用shi的其他的方法了. 这就是链式调用.
扩展jquery的方法
首先, 如果你对js的方法不是那么明白. 请看这里或者google去. 我们基本上, 需要明白的是函数类和c#的类一样. 有静态成员和实例成员.好吧, 我们来看一个简单的例子. 还是在这里 (=, =)
因此. 我们要扩展jquery的话, 无非就是扩展init函数类的实例方法,和jquery的静态方法. 而扩展init的实例方法怎么实现呢? 因为init实例对象通过jquery.prototype.init.prototype = $.prototype获得了jquery.prototype的所有成员, 所以呢, 我们只要在jquery.prototype里面增加新的对象, 那么就可以用类似于$(document.getElementById(‘div’))这样的操作来使用该方法了.
好吧, 我们先需要两个接口来给外界为它增加方法.
$.extend = function (obj) {
for (var i in obj) {jquery[i] = obj[i];}}$.prototype.extend = function (obj) {
for (var i in obj) {jquery[i] = obj[i];}}第一个方法是给jquery增加静态方法, 我们来增加一个合并两个数组并且去重复的方法$.extend({ mergeArray: function (arr1, arr2) {
newarr = arr1.join(',') + ",";for (var i = 0; i < arr2.length; i++) {var reg = new RegExp(arr2[i] + ",", "g");newarr = newarr.replace(reg, "") + arr2[i] + ",";}return newarr;
}});//调用 alert($.mergeArray([1, 2, 3], [3, 4, 5]));//1,2,3,4,5,
第二个方法当然是给jquery增加实例方法了. 那么我们返回jquery的第一个对象(jquery是一个伪数组, 当然, 我们自己实现的jquery虽然也是个伪数组, 不过却只有一个元素), first: function () {
var temp = this[0];this[0] = temp;
this.length = 1;
return this;}我们给init暂时增加一段代码. 如果第二个参数有的话, 那么是则是查找所有的某个html元素if (typeof context == "string") {var nodes = document.getElementById(context).getElementsByTagName(selector);
Array.prototype.push.apply(this, nodes);
this.length = nodes.length;
return this;}假设一个ID为div1的div里面有很多div<div id="div1"><div>子div1</div><div>子div2</div></div>现在我们再增加一个last的实例方法. 并测试一下
alert($("div", "div1").css({ color: 'red' }).first()[0].innerHTML);alert($("div", "div1").css({ color: 'red' }).last()[0].innerHTML)可以看到, 两个div的字体颜色都发生了改变. 并且对话框把各自查询的内容显示了出来.
好了. 最后我们来看看我们现在拥有的jquery的代码
(function () {
var jquery = window.jquery = $ = window.$ = function (selector, context) {return new jquery.fn.init(selector, context);}$.prototype = jquery.fn = jquery.prototype = {init: function (selector, context) {
if (selector.nodeType == 1) {
this[0] = selector;
this.length = 1;
return this;}if (typeof context == "string") {var nodes = document.getElementById(context).getElementsByTagName(selector);
Array.prototype.push.apply(this, nodes);
this.length = nodes.length;
return this;}if (!selector)
return this;}, css: function (cssjson) {
for (var i = 0; i < this.length; i++) {for (var stylename in cssjson) {this[i].style[stylename] = cssjson[stylename];
}}return this;}, first: function () {
var temp = this[0];this[0] = temp;
this.length = 1;
return this;}, last: function () {
var temp = this[this.length - 1];this[0] = temp;
this.length = 1;
return this;}}$.extend = function (obj) {
for (var i in obj) {jquery[i] = obj[i];}}$.prototype.extend = function (obj) {
for (var i in obj) {jquery[i] = obj[i];}}jquery.prototype.init.prototype = $.prototype;})();