其实,封装jquery插件很简单。
先看看,封装模板是什么?看下这个light-weight模式:
-
11121314151617181920212223242526272829303132333435363738394041propertyName : "value"}//插件类function Plugin ( element , options ) {//拿到dom元素,获得对应jq对象,要$(element)this.element = element;//覆盖默认配置项this.options = $.extend({},defaults,options);//缓存配置项this._defaults = defaults;//缓存插件名字(并没神马用)this._name = pluginName;//调用初始函数this.init();}Plugin . prototype . init = function ( ) {//做你想做的事情}//fn就是prototype$ . fn [ pluginName ] = function ( options ) {//each表示对多个元素调用,用return 是为了返回this,进行链式调用return this.each(function(){//判断有没有插件名字 如果你不愿意加if 直接new就好了if(!$.data(this,'plugin_'+pluginName)){//生成插件类实例。$.data(this,'plugin_'+pluginName,new Plugin(this,options));}});}})(jQuery,window,document);//注意没有传第四个参数。
第一步 ,先写出简单demo,这里不写了,直接找一个吧。这里以一个tab选项卡为例
运行效果如下:
-
6789101112131415161718192021222324252627282930313233343536<script type="text/javascript">$(function(){$ ( document ) . ready ( function ( ) {$(".tab li").click(function(){$(".tab li").eq($(this).index()).addClass("cur").siblings().removeClass('cur');$("div").hide().eq($(this).index()).show();//另一种方法: $("div").eq($(".tab li").index(this)).addClass("on").siblings().removeClass('on');});});});</script><style>div{margin: 0; padding: 0; width: 184px; height: 200px; border: 1px solid #ccc; display: none; }.tab{margin: 0; padding: 0; list-style: none; width: 200px; overflow: hidden; }.tab li{float: left; width: 60px; height: 30px; background: #ccc; color: #fff; border: 1px solid red; text-align: center; line-height: 30px; cursor: pointer; }.on{display: block; }.tab li.cur{background: blue; }</style></head><body><ul class="tab"><li>最新</li><li class="cur">热门</li><li>新闻</li></ul><div>11</div><div class="on">22</div><div>33</div></body></html>
假设是自己写的,先看看核心逻辑是什么?
-
1234567$(document).ready(function(){$(".tab li").click(function(){$(".tab li").eq($(this).index()).addClass("cur").siblings().removeClass('cur');$("div").hide().eq($(this).index()).show();//另一种方法: $("div").eq($(".tab li").index(this)).addClass("on").siblings().removeClass('on');});});
很简单,不做过多说明了。
第二步 ,改写代码为封装插件做准备,原文中的是index为顺序的,我想不要这种顺序,改用data属性来指明那个tab对应那个div。
先给内容区域,总体用div包装一下,同样要改变样式。
tab页和内容区域做关联,改用data属性关联。
-
123456789$(document).ready(function(){$(".tab li").click(function(){var $this = $(this);var c = $this.data("tab");alert(c)$this.addClass("cur").siblings().removeClass('cur');$(".tabContent").find('>[data-tab='+c+']').addClass("on").siblings().removeClass('on');});});
-
78910111213141516171819202122232425262728293031323334353637$(document).ready(function(){$(".tab li").click(function(){var $this = $(this);var c = $this.data("tab");$this.addClass("cur").siblings().removeClass('cur');$(".tabContent").find('>[data-tab='+c+']').addClass("on").siblings().removeClass('on');});});</script><style>.tabContent div{margin: 0; padding: 0; width: 184px; height: 200px; border: 1px solid #ccc; display: none; }.tab{margin: 0; padding: 0; list-style: none; width: 200px; overflow: hidden; }.tab li{float: left; width: 60px; height: 30px; background: #ccc; color: #fff; border: 1px solid red; text-align: center; line-height: 30px; cursor: pointer; }.tab li.cur{background: blue; }div.on{display: block; }</style></head><body><ul id="tab" class="tab"><li data-tab="tab1">最新</li><li data-tab="tab2" class="cur">热门</li><li data-tab="tab3">新闻</li></ul><div id="tabContent" class="tabContent"><div data-tab="tab1">11</div><div data-tab="tab2" class="on">22</div><div data-tab="tab3">33</div></div></body></html>
第三步 ,用模板来封装插件,套用就行了,我做一个可以支持默认激活某一项的配置。
-
891011121314151617181920212223242526272829303132333435363738this.element = element;this.options = $.extend({},defaults,options);this._defaults = defaults;this._name = pluginName;this.init();}Plugin . prototype . init = function ( ) {var self = this;$(this.element).find('li').click(function(){var $this = $(this);var name = $this.data("tab");$this.addClass("cur").siblings().removeClass('cur');$(self.options.contentWrapper).find('>[data-tab='+name+']').addClass("on").siblings().removeClass('on');});var activeName = this.options.activeTabName;alert(activeName);if(activeName == null){$(this.element).find('li').eq(0).click();}else{$(this.element).find('>[data-tab='+activeName+']').click();}}$ . fn [ pluginName ] = function ( options ) {return this.each(function(){if(!$.data(this,'plugin_'+pluginName)){$.data(this,'plugin_'+pluginName,new Plugin(this,options));}});}})(jQuery,window,document);
使用方式:
-
1$('#tab').myTab({contentWrapper:'#tabContent',activeTabName : 'tab2'});
第四步 ,代码优化,每个li都有click,太浪费了。改用委托(原先用的delegate,经网友提醒,包括bind,我全改成on了)。
-
15161718192021222324252627282930313233343536373839404142434445var self = this;var $element = $(this.element);$element.on('click','li',function(){var $this = $(this);var c = $this.data("tab");$element.trigger('tab/change',c);});$element.on('tab/change',function(e,tabName){$element.find('li').removeClass('cur');$element.find('>[data-tab='+tabName+']').addClass("cur");});var $contentWrapper = $(this.options.contentWrapper);$element.on('tab/change',function(e,tabName){$contentWrapper.find('>[data-tab]').removeClass('on');$contentWrapper.find('>[data-tab='+tabName+']').addClass("on");});var activeName = this.options.activeTabName;if(activeName == null){$element.find('li').eq(0).click();}else{$element.trigger('tab/change',this.options.activeTabName);}}$ . fn [ pluginName ] = function ( options ) {return this.each(function(){if(!$.data(this,'plugin_'+pluginName)){$.data(this,'plugin_'+pluginName,new Plugin(this,options));}});}})(jQuery,window,document);
完整案例
-
48495051525354555657585960616263646566676869707172737475767778}});}})(jQuery,window,document);</script><script type="text/javascript">$(function(){$ ( '#tab' ) . myTab ({contentWrapper:'#tabContent',activeTabName : 'tab2'});})</script><style>.tabContent div{margin: 0; padding: 0; width: 184px; height: 200px; border: 1px solid #ccc; display: none; }.tab{margin: 0; padding: 0; list-style: none; width: 200px; overflow: hidden; }.tab li{float: left; width: 60px; height: 30px; background: #ccc; color: #fff; border: 1px solid red; text-align: center; line-height: 30px; cursor: pointer; }.tab li.cur{background: blue; }div.on{display: block; }</style></head><body><ul id="tab" class="tab"><li data-tab="tab1">最新</li><li data-tab="tab2">热门</li><li data-tab="tab3">新闻</li></ul><div id="tabContent" class="tabContent"><div data-tab="tab1">11</div><div data-tab="tab2">22</div><div data-tab="tab3">33</div></div></body></html>
如你所料,封装插件过程很简单,难的还是业务逻辑。
一般插件还要支持传入字符串当方法调用的,这里面没写,以后可能会补充进去。
比如有方法支持让第几个激活。还有,还要支持AMD的,这里只是一个简单例子,没有写进去。
本文完。