JS封装——构建自己的jQuery插件

参与的多个项目有时候需要复用一些功能,那么就希望能把一些功能进行封装,提高易用性和代码复用性。
直接上个简单的栗子,详情见imageCarousel:

 (function ( $, window, document) {
    var pluginName = "imageCarousel",
    
    //默认配置参数  default settings
    defaults = {
        speed:300,    //滑动速度 slide speed
        autoSlide:true,    //是否主动滑动 slide automatically
        holdTime:4000,      //主动滑动时图片停留时间 the time to hold image between two slidings
        alwaysShowTitle:true, //是否一直显示图片标题 
        color:"#000",   //字体颜色 font color
        clickImage:function(element,index){}, //点击图片时回调函数,参数:element:图片元素,index:图片在图片数组中的序号
    };
    
    // The actual plugin constructor
    function Plugin ( element, images,options ) {
            this.element = element;
            this.images = images;
            this.settings = $.extend( {}, defaults, options );
            this._defaults = defaults;
            this._name = pluginName;
            this.init();
    };
    
    Plugin.prototype = {
            init: function () {   //初始化
                var e = this;
                e.width = $(e.element).width();
                e.height = $(e.element).height();
                $(e.element).addClass("imageCarouselBox");
                $(e.element).css("color",e.settings.color);
                e.picTimer;
                e.setImages(e.images);
            },
                        
            setImages:function(images){  //设置图片数组,可以用于修改当前播放的图片数组
                var e = this;
                e.dataLength = e.images.length;
                $(e.element).html("");
                e.index = 0;
                var ulText = "
    " var btnText = "
    "; for(var i=0; i < e.dataLength; i++) { btnText += ""; ulText += "
  • "+images[i].title+"
  • "; //插入图片 } btnText += "
    "; ulText += "
"; $(e.element).append(ulText); $(e.element).append(btnText); $(e.element).find("ul").css("width",e.width * e.dataLength); $(e.element).find("ul li").css("width",e.width).click(function(){ e.settings.clickImage(this,e.index); }); if(e.settings.alwaysShowTitle){ $(e.element).find("ul li .text-box").fadeIn(); } else{ $(e.element).find("ul li").mouseenter(function(){ $(this).find(".text-box").fadeIn(); }).mouseleave(function(){ $(this).find(".text-box").fadeOut(); }); } $(e.element).find(".btn span").css("opacity",0.4).mouseenter(function() { e.index = $(e.element).find(".btn span").index(this); e.showImage(e.index); }).eq(0).trigger("mouseenter"); $(e.element).find(" .preNext").css("opacity",0.2).hover(function() { $(this).stop(true,false).animate({"opacity":"0.5"},e.settings.speed); },function() { $(this).stop(true,false).animate({"opacity":"0.2"},e.settings.speed); }); $(e.element).find(" .pre").click(function() { e.index -= 1; if(e.index == -1) {e.index = e.dataLength - 1;} e.showImage(e.index); }); $(e.element).find(" .next").click(function() { e.index += 1; if(e.index == e.dataLength) {e.index = 0;} e.showImage(e.index); }); if(e.settings.autoSlide){ $(e.element).hover(function() { clearInterval(e.picTimer); },function() { e.picTimer = setInterval(function() { e.showImage(e.index); e.index++; if(e.index == e.dataLength) {e.index = 0;} },e.settings.holdTime); }).trigger("mouseleave"); } }, showImage: function(index){ //切换当前显示的图片 var e = this; var nowLeft = -index*e.width; $(e.element).find("ul").stop(true,false).animate({"left":nowLeft},e.settings.speed); $(e.element).find(" .btn span").stop(true,false).animate({"opacity":"0.4"},e.settings.speed) .eq(index).stop(true,false).animate({"opacity":"0.8"},e.settings.speed); } }; $.fn[ pluginName ] = function ( images,options) { //向jQuery注册插件 var e = this; e.each(function() { $.data( e, "plugin_" + pluginName, new Plugin( this,images, options ) ); }); return e; }; })(jQuery, window, document)

以上代码封装了一个jQuery图片轮播插件。

1. 用匿名函数封装组件

首先看看如下写法:

(function ( $, window, document) {
  //....封装组件逻辑
})(jQuery, window, document);

这就是一个匿名函数的形式。将它拆开来看如下:

var fn = function($, window, document){
  //....封装组件逻辑
};
fn(jQuery, window, document);

也就是说这种写法就表示先定义一个方法,然后立即调用这个方法,jQuery相当于实参。打开jquery.js的原文件可以看到,jQuery是这个文件里面的一个全局变量。

2. 向jQuery注册组件

先直接看上面栗子的最后几行代码:

$.fn[ pluginName ] = function ( images,options) {   //向jQuery注册插件
    var e = this;
    e.each(function() {
        $.data( e, "plugin_" + pluginName, new Plugin( this,images, options ) );
    });
    return e;
};

由于在栗子最前面我们定义了

var pluginName = "imageCarousel";

那么

$.fn[ pluginName ] = function ( images,options) { 
  //...
}

在jQuery中注册了一个名为imageCarousel的函数及其参数,与jQuery自带的函数一样,可以通过以下方法调用:

$(element).imageCarousel(images,options);

e.each(function() {
    $.data( e, "plugin_" + pluginName, new Plugin( this,images, options ) );
});

则向当前元素添加了一个名为“plugin_imageCarousel”的属性,它的值为 new Plugin( element,images, options )。
也就是说,

$(element).imageCarousel(images,options);

这行代码实际上会向元素中添加“plugin_imageCarousel”属性,并执行了:

$(element).plugin_imageCarousel = new Plugin( element,images, options );

3. 定义组件的构造函数

function Plugin ( element, images,options ) {
    this.element = element;
    this.images = images;
    this.settings = $.extend( {}, defaults, options );
    this._defaults = defaults;
    this._name = pluginName;
    this.init();
};

构造函数保护了插件的各个参数包括默认参数,然后调用了插件的 prototype 中定义的 init 方法。

4. 定义插件的行为

imageCarousel 插件在 Plugin.prototype中定义了init()、setImages(images)、showImage(index)这几个函数,具体作用不用展开说明。这些函数可以用以下方法调用:

$(element).plugin_imageCarousel.init();
$(element).plugin_imageCarousel.setImages(images);
$(element).plugin_imageCarousel.showImage(index);

5. 定义组件的配置参数

有时候我们希望能够自定义组件的一些属性或行为,那么就可以定义一组配置参数:

//默认配置参数  default settings
    defaults = {
        speed:300,    //滑动速度 slide speed
        autoSlide:true,    //是否主动滑动 slide automatically
        holdTime:4000,      //主动滑动时图片停留时间 the time to hold image between two slidings
        alwaysShowTitle:true, //是否一直显示图片标题 
        color:"#000",   //字体颜色 font color
        clickImage:function(element,index){}, //点击图片时回调函数,参数:element:图片元素,index:图片在图片数组中的序号
    };

这些参数预先设置了默认值,那么在使用的时候是如何自定义的呢?
在组件的构造函数中可以看到这样一句代码:

...
this.settings = $.extend( {}, defaults, options );
...

jquery的extend()方法作用是合并另个对象,有相同的则覆盖,没有相同的则添加。也就是说,上面这行代码中options对象中的参数会覆盖defaults对象中同名的参数,这就实现了配置参数自定义的目的。

你可能感兴趣的:(JS封装——构建自己的jQuery插件)