參與的多個(gè)項(xiàng)目有時(shí)候需要復(fù)用一些功能,那么就希望能把一些功能進(jìn)行封裝,提高易用性和代碼復(fù)用性。
直接上個(gè)簡(jiǎn)單的栗子,詳情見(jiàn)imageCarousel:
(function ( $, window, document) {
var pluginName = "imageCarousel",
//默認(rèn)配置參數(shù) default settings
defaults = {
speed:300, //滑動(dòng)速度 slide speed
autoSlide:true, //是否主動(dòng)滑動(dòng) slide automatically
holdTime:4000, //主動(dòng)滑動(dòng)時(shí)圖片停留時(shí)間 the time to hold image between two slidings
alwaysShowTitle:true, //是否一直顯示圖片標(biāo)題
color:"#000", //字體顏色 font color
clickImage:function(element,index){}, //點(diǎn)擊圖片時(shí)回調(diào)函數(shù),參數(shù):element:圖片元素,index:圖片在圖片數(shù)組中的序號(hào)
};
// 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){ //設(shè)置圖片數(shù)組,可以用于修改當(dāng)前播放的圖片數(shù)組
var e = this;
e.dataLength = e.images.length;
$(e.element).html("");
e.index = 0;
var ulText = "<ul>"
var btnText = "<div class='btnBg'><div class='btn'>";
for(var i=0; i < e.dataLength; i++) {
btnText += "<span></span>";
ulText += "<li ><img src='"+images[i].path+"' alt='' ><div class='text-box'>"+images[i].title+"</div></li>"; //插入圖片
}
btnText += "</div></div><div class='preNext pre'></div><div class='preNext next'></div>";
ulText += "</ul>";
$(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){ //切換當(dāng)前顯示的圖片
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注冊(cè)插件
var e = this;
e.each(function() {
$.data( e, "plugin_" + pluginName, new Plugin( this,images, options ) );
});
return e;
};
})(jQuery, window, document)
以上代碼封裝了一個(gè)jQuery圖片輪播插件。
1. 用匿名函數(shù)封裝組件
首先看看如下寫法:
(function ( $, window, document) {
//....封裝組件邏輯
})(jQuery, window, document);
這就是一個(gè)匿名函數(shù)的形式。將它拆開來(lái)看如下:
var fn = function($, window, document){
//....封裝組件邏輯
};
fn(jQuery, window, document);
也就是說(shuō)這種寫法就表示先定義一個(gè)方法,然后立即調(diào)用這個(gè)方法,jQuery相當(dāng)于實(shí)參。打開jquery.js的原文件可以看到,jQuery是這個(gè)文件里面的一個(gè)全局變量。
2. 向jQuery注冊(cè)組件
先直接看上面栗子的最后幾行代碼:
$.fn[ pluginName ] = function ( images,options) { //向jQuery注冊(cè)插件
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中注冊(cè)了一個(gè)名為imageCarousel的函數(shù)及其參數(shù),與jQuery自帶的函數(shù)一樣,可以通過(guò)以下方法調(diào)用:
$(element).imageCarousel(images,options);
而
e.each(function() {
$.data( e, "plugin_" + pluginName, new Plugin( this,images, options ) );
});
則向當(dāng)前元素添加了一個(gè)名為“plugin_imageCarousel”的屬性,它的值為 new Plugin( element,images, options )。
也就是說(shuō),
$(element).imageCarousel(images,options);
這行代碼實(shí)際上會(huì)向元素中添加“plugin_imageCarousel”屬性,并執(zhí)行了:
$(element).plugin_imageCarousel = new Plugin( element,images, options );
3. 定義組件的構(gòu)造函數(shù)
function Plugin ( element, images,options ) {
this.element = element;
this.images = images;
this.settings = $.extend( {}, defaults, options );
this._defaults = defaults;
this._name = pluginName;
this.init();
};
構(gòu)造函數(shù)保護(hù)了插件的各個(gè)參數(shù)包括默認(rèn)參數(shù),然后調(diào)用了插件的 prototype 中定義的 init 方法。
4. 定義插件的行為
imageCarousel 插件在 Plugin.prototype中定義了init()、setImages(images)、showImage(index)這幾個(gè)函數(shù),具體作用不用展開說(shuō)明。這些函數(shù)可以用以下方法調(diào)用:
$(element).plugin_imageCarousel.init();
$(element).plugin_imageCarousel.setImages(images);
$(element).plugin_imageCarousel.showImage(index);
5. 定義組件的配置參數(shù)
有時(shí)候我們希望能夠自定義組件的一些屬性或行為,那么就可以定義一組配置參數(shù):
//默認(rèn)配置參數(shù) default settings
defaults = {
speed:300, //滑動(dòng)速度 slide speed
autoSlide:true, //是否主動(dòng)滑動(dòng) slide automatically
holdTime:4000, //主動(dòng)滑動(dòng)時(shí)圖片停留時(shí)間 the time to hold image between two slidings
alwaysShowTitle:true, //是否一直顯示圖片標(biāo)題
color:"#000", //字體顏色 font color
clickImage:function(element,index){}, //點(diǎn)擊圖片時(shí)回調(diào)函數(shù),參數(shù):element:圖片元素,index:圖片在圖片數(shù)組中的序號(hào)
};
這些參數(shù)預(yù)先設(shè)置了默認(rèn)值,那么在使用的時(shí)候是如何自定義的呢?
在組件的構(gòu)造函數(shù)中可以看到這樣一句代碼:
...
this.settings = $.extend( {}, defaults, options );
...
jquery的extend()方法作用是合并另個(gè)對(duì)象,有相同的則覆蓋,沒(méi)有相同的則添加。也就是說(shuō),上面這行代碼中options對(duì)象中的參數(shù)會(huì)覆蓋defaults對(duì)象中同名的參數(shù),這就實(shí)現(xiàn)了配置參數(shù)自定義的目的。