引子


 

现在网上关于js和jquery封装的插件很多,我刚刚接触前端的时候,就很敬佩那些自己写插件的大牛们!因为是他们给网站开发更多的便利,很多网页效果,网上很多现成的插件!那么这些插件是如何写的呢?首先是有扎实的js和jquery技术基础,其次还有一些写插件的方法和技巧。关于js和jquery的技术基础,那是一个慢慢积累的过程。但是关于写插件的一些注意和技巧,本文可以略微介绍一下,方便以后写插件的时候用得到。

要说jQuery 最成功的地方,我认为是它的可扩展性吸引了众多开发者为其开发插件,从而建立起了一个生态系统。这好比大公司们争相做平台一样,得平台者得天下。苹果,微软,谷歌等巨头,都有各自的平台及生态圈。

学会使用jQuery并不难,因为它简单易学,并且相信你接触jQuery后肯定也使用或熟悉了不少其插件。如果要将能力上升一个台阶,编写一个属于自己的插件是个不错的选择。

 

jquery插件开发模式


 

软件开发过程中是需要一定的设计模式来指导开发的,有了模式,我们就能更好地组织我们的代码,并且从这些前人总结出来的模式中学到很多好的实践。

根据《jQuery高级编程》的描述,jquery插件一般有三种开发方式:



通过$.extend()来扩展jQuery
通过$.fn 向jQuery添加新的方法
通过$.widget()应用jQuery UI的部件工厂方式创建



通常我们使用第二种方法来进行简单插件开发,说简单是相对于第三种方式。第三种方式是用来开发更高级jQuery部件的,该模式开发出来的部件带有很多jQuery内建的特性,比如插件的状态信息自动保存,各种关于插件的常用方法等,非常贴心,这里不细说。

而第一种方式又太简单,仅仅是在jQuery命名空间或者理解成jQuery身上添加了一个静态方法而以。所以我们调用通过$.extend()添加的函数时直接通过$符号调用($.myfunction())而不需要选中DOM元素($('#example').myfunction())。



$.extend({
    sayHello: function(name) {
        console.log('Hello,' + (name ? name : 'Dude') + '!');
    }
})
$.sayHello(); //调用
$.sayHello('test'); //带参调用



但这种方式无法利用jQuery强大的选择器带来的便利,要处理DOM元素以及将插件更好地运用于所选择的元素身上,还是需要使用第二种开发方式。你所见到或使用的插件也大多是通过此种方式开发。

 

 

插件开发


 

第二种插件开发方式一般是如下定义



$.fn.pluginName = function() {
    //your code here
}



插件开发,我们一般运用面向对象的思维方式
例如定义一个对象



var testObj= function(el, opt) {
    this.$element = el,
    this.defaults = {
        'color': 'red',
        'fontSize': '12px',
        'textDecoration':'none'
    },
    this.options = $.extend({}, this.defaults, opt)
}
//定义testObj的方法
testObj.prototype = {
    changecss: function() {
        return this.$element.css({
            'color': this.options.color,
            'fontSize': this.options.fontSize,
            'textDecoration': this.options.textDecoration
        });
    }
}



$.extend({}, this.defaults, opt)有{}主要是为了创建一个新对象,保留对象的默认值。



$.fn.myPlugin = function(options) {
    //创建haorooms的实体
    var testIndividual= new testObj(this, options);
    //调用其方法
    return testIndividual.changecss();
}



调用这个插件直接如下就可以



$(function() {
    $('a').myPlugin({
        'color': '#2C9929',
        'fontSize': '20px'
    });
})



 

上述开发方法的问题


 

上面的开发方法存在一个严重的问题,就是定义了一个全局的testObj,这样对于插件的兼容等等各个方面都不好。万一别的地方用到了testObj,那么你的代码就悲催了!现在我们把上面的代码包装起来,用一个自调用匿名函数(有时又叫块级作用域或者私有作用域)包裹,就不会出现这个问题了!包括js插件的开发,也是一样的,我们用一个自调用匿名函数把自己写的代码包裹起来,就可以了!包裹方法如下:



(function(){

})()



用上面的这个包裹起来,就可以了。
但是还有一个问题,当我们研究大牛的代码的时候,前面经常看到有“;”,那是为了避免代码合并等不必要的错误。
例如,我们随便定义一个函数:



var testFunction=function(){

}
(function(){

})()



由于testFunction()这个函数后面没有加分号,导致代码出错,为了避免这类情况的发生,通常这么写!



;(function(){

})()



基本上可以说是完美了。但是为了让你开发的插件应用更加广泛,兼容性更加好,还要考虑到用插件的人的一些特殊的做法,例如,有些朋友为了避免jquery和zeptojs冲突,将jquery的前缀“$”,修改为“jQuery”,还有些朋友将默认的document等方法修改。为了让你的插件在这些东西修了了的情况下照常运行,那么我们的做法是,把代码包裹在如下里面:



;(function($,window,document,undefined){
    //我们的代码。。
})(jQuery,window,document);



就可以避免上面的一些情况了!
至此,你开发的插件就算完美了!

 

补充


 

JQ插件标准的封装---闭包



<script type="text/javascript">
    (function ($) {
        //这里放入插件代码
    })(jQuery);
</script>



这是jQuery官方的插件开发规范,这样写是作用是:
1. 避免全局依赖。
2. 避免第三方破坏。
3. 兼容jQuery操作符’$’和’jQuery’

这段代码在被解析时会形同如下代码:



var jq = function($) {
    // Code goes here
}; 
jq(jQuery);



 

================更新于2016年2月4日=============

编写插件



$(function () {
    $.fn.插件名称 = function (options) {
        var defaults = {
            Event : "click", //触发响应事件
            msg : "Holle word!" //显示内容
        };
        var options = $.extend(defaults, options);
        var $this = $(this); //当然响应事件对象
        //功能代码部分
        //绑定事件
        $this.live(options.Event, function (e) {
            alert(options.msg);
        });
    }
});



调用插件



$(function () {
    //绑定元素事件
    $("#test").插件名称({
        Event : "click", //触发响应事件
        msg : "插件原来就是这么简单!" //显示内容
    });
});



布局



<input type = "button" id = "test" value = "这是一个简单的插件调用" /  >