前言
以前在写网页上常用的功能时,经常差不多同样的js代码会重复好几遍,而重来没想过把它封装起来,增加代码的复用性。最近把一些常用的功能封装了一下,而jquery插件式的封装方法也是几经周折、查了一些资料才弄出来的。下面就用最常用的选项卡为例子来说明一下吧。
正文 首先,jquery官方是提供了一个写插件的模板的,像superSlide 等插件就是基于这样的模板写的。然而一开始我并不知道有这样一个模板,我想写出类似于superSlide这样调用的效果$(selector).slide({})
,我当时的理解是:slide()
肯定是一个jquery对象$(selector)
的方法,也是因为原型那一块没学好,在那里苦思冥想怎么把这个方法挂到每一个jquery对象的实例上呢?现在可以事后诸葛亮的说直接把方法挂在jquery对象的原型上,通过继承链继承不就好了?恩,扯远了,先把模板代码贴一下吧,然后再解释下这个模板:
jquery插件模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ;(function ($ ) { $.fn.plugin = function (options ) { var defaults = { } var opts = $.extend({},defaults,options); this .each(function ( ) { }); return this ; } })(jQuery);
把上面的代码简化一下就是(function($){})(jQuery);
,还有另一种写法(function($){}(jQuery));
,效果是一样的 (其实jquery的源码也是采用这种形式的(function(window,undefined){})(window)
)。这种形式就是一个匿名函数自执行,把所有的代码封装在里面就避免了污染全局对象,在浏览器里也就是window对象。前面加一个;
是为了避免与其它的库或代码产生”摩擦”。再看这段代码$.fn.plugin = function(options){}
,$.fn
实际上就是jQuery的原型prototype,那$.fn.plugin
就相当于在jQuery的原型上定义了一个方法,这个方法接收一个参数options
,这个参数是一个对象。这个方法内部的代码又可以分为4大块:
var defaults = {};
把功能代码中可能会变化的变量(比如dom节点)提取出来,给一个默认的值,组成一个对象,方便调用者在调用的时候按照需求修改,如果调用的时候什么都不传,就用默认的。
var opts = $.extend({},defaults,options);
关于$.extend()
的具体用法,可以参看官方文档中对这个API的说明 。其实粗略的理解就是把defaults和options这两个对象合并起来成为一个新的对象opts(后面功能代码里用到的变量都是用的opts这个对象的属性),options里的属性值会覆盖掉defaults里的属性值,options里没有的属性,就用defaults里提供的默认属性值。
this.each(function(){});
实现功能的代码都往这里面扔就好了,没什么好说的。
return this;
返回值this就是对应dom节点的jquery对象,比如$('.tab')
。加上这个返回值才能支持链式操作,比如$('.tab').plugin().sinbling()...
示例demo代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <div class ="tab" > <div class ="tab-title" > <ol class ="clearfix" > <li > 1</li > <li > 2</li > <li > 3</li > </ol > </div > <div class ="tab-cont" > <ul class ="clearfix" > <li > 内容1</li > <li > 内容2</li > <li > 内容3</li > </ul > </div > </div >
1 2 3 4 5 6 7 8 9 10 11 12 13 * { margin :0 ; padding :0 ;} li { list-style : none;}.clearfix :after { content : "" ; display : block ;height : 0 ;clear : both ;visibility : hidden ;} .tab-title li { float : left; width : 100px ; height : 50px ; text-align : center;cursor :pointer; line-height : 50px ;}.tab-title li .on { background : purple; color : #fff ;}.tab-cont li { width : 300px ; height : 300px ;text-align : center; border : 1px solid #333 ;}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 ;(function ($ ) { $.fn.funTab = function (options ) { $.fn.funTab.defaults = { titItem: '.tab-title li' , contItem: '.tab-cont li' , trigger: 'mouseover' , titOnClassName: 'on' }; var opts = $.extend({},$.fn.funTab.defaults,options); this .each(function ( ) { var funTaber = $(this ); funTaber.find(opts.titItem).eq(0 ).addClass(opts.titOnClassName); funTaber.find(opts.contItem).eq(0 ).show().siblings().hide(); var index; funTaber.find(opts.titItem).bind(opts.trigger,function ( ) { $(this ).addClass(opts.titOnClassName).siblings().removeClass(opts.titOnClassName); var index = funTaber.find(opts.titItem).index(this ); funTaber.find(opts.contItem).eq(index).show().siblings().hide(); }) }); return this ; } })(jQuery);
1 2 3 4 5 $('.tab' ).funTab({ titItem:'.tab-title li' ,contItem :'.tab-cont li' ,trigger :'click' ,titOnClassName :'on' });