首页 / 世界杯吉祥物

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

2025-06-10 23:02:15世界杯吉祥物 2904

参与的多个项目有时候需要复用一些功能,那么就希望能把一些功能进行封装,提高易用性和代码复用性。

直接上个简单的栗子,详情见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对象中同名的参数,这就实现了配置参数自定义的目的。