深入了解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;
 
})();
posted @ 2011-06-13 16:23  MyCoolDog  阅读(494)  评论(0编辑  收藏  举报