jQuery插件开发的五种形态小结

关于jQuery插件的开发自己也做了少许研究,自己也写过多个插件,在自己的团队了也分享过一次关于插件的课。开始的时候整觉的很复杂的代码,现在再次看的时候就清晰了许多。这里我把我自己总结出来的东西分享出来,帮助那些和我一样曾经遇到过同样问题的人。

我要做什么
我想要得到的javascript 插件应该会有以下几个特征

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

* 以下的代码均假设存在 jQuery

插件的第一形态

面对这种情况,通常我们会通过定义function的方式来实现。

复制代码 代码如下:


function pluginName($selector){
    $.each($selector, function () {
        $(this).css("background-color", "#ccc");
        // to do something...
    });
}
// pluginName(document.getElementsByClassName("demo"));

因为我谈的是jQuery插件开发,那么我现在把这段代码扩展到jQuery上,代码如下:

复制代码 代码如下:


// IIFE(立即调用函数表达式);  [参考 ]
;(function ($) {
    // 扩展这个方法到jQuery.
    // $.extend() 是吧方法扩展到 $ 对象上,和 $.fn.extend 不同。 扩展到 $.fn.xxx 上后,
    // 调用的时候就可以是 $(selector).xxx()
    $.fn.extend({
        // 插件名字
        pluginName: function () {
            // 遍历匹配元素的集合
            // 注意这里有个"return",作用是把处理后的对象返回,实现链式操作
            return this.each(function () {
                // 在这里编写相应的代码进行处理
            });
        }
    });
// 传递jQuery到内层作用域去, 如果window,document用的多的话, 也可以在这里传进去.
// })(jQuery, window, document, undefined);
})(jQuery, undefined);
// 调用方式 $(".selector").pluginName().otherMethod();

但是还差的远,目前只解决了两个问题

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

插件的第二形态

现在来给插件添加参数支持。代码如下

复制代码 代码如下:


;(function($){
    $.fn.pluginName = function(options) {
        // 合并参数,通过“extend”合并默认参数和自定义参数
        var args = $.extend({}, $.fn.pluginName.defaults, options);
        return this.each(function() {
            console.log(args.text);
            // to do something...
        });
    };
    // 默认参数
    $.fn.pluginName.defaults = {
        text : "hello"
    };
})(jQuery);
// $(".selector").pluginName({
//     text : "hello world!"
// });

添加参数支持还比较容易些,又解决一问题

代码相对独立
链式操作
插件可配置
有可操作的方法,插件的生命周期可控制
配置可被缓存
可扩展
无冲突处理
事件代理,动态初始化

插件的第三形态

现在来添加方法的支持,我前面所提到的生命周期可控制,意思差不多,例如添加reInit,destory等方法来控制插件。

复制代码 代码如下:


;(function($){
    $.fn.pluginName = function (method) {
        // 如果第一个参数是字符串, 就查找是否存在该方法, 找到就调用; 如果是object对象, 就调用init方法;.
        if (methods[method]) {
            // 如果存在该方法就调用该方法
            // apply 是吧 obj.method(arg1, arg2, arg3) 转换成 method(obj, [arg1, arg2, arg3]) 的过程.
            // Array.prototype.slice.call(arguments, 1) 是把方法的参数转换成数组.
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            // 如果传进来的参数是"{...}", 就认为是初始化操作.
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on jQuery.pluginName');
        }
    };
    // 不把方法扩展在 $.fn.pluginName 上. 在闭包内建个"methods"来保存方法, 类似共有方法.
    var methods = {
        /**
         * 初始化方法
         * @param _options
         * @return {*}
         */
        init : function (_options) {
            return this.each(function () {
                var $this = $(this);
                var args = $.extend({}, $.fn.pluginName.defaults, _options);
                // ...
            })
        },
        publicMethod : function(){
            private_methods.demoMethod();
        }
    };
    // 私有方法
    function private_methods = {
        demoMethod : function(){}
    }
    // 默认参数
    $.fn.pluginName.defaults = {
    };
})(jQuery);
// 调用方式
// $("div").pluginName({...});  // 初始化
// $("div").pluginName("publicMethod");  // 调用方法

又解决一问题

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgfgfj.html