一步一步制作jquery插件Tabs实现过程


Posted in Javascript onJuly 06, 2010

tabs是现在网页应用最广的一种效果,jquery插件和非jquery插件也有不少,有一些朋友问我怎么用jquery.ui.tabs的ajax怎么只请求服务器一次原来我想其实很简单,看看官方的API就了解,不过我在回复这些朋友之前,用firebug查看了官方的ui.tabs发现,声明了ajax缓存,每点一个tabs时,仍然会有服务器请求这应该是服务器缓存,而不是实际上我们要求的只ajax一次,不再请求服务器了接下来我找了一下其它的tabs插件,基本上没有符合要求的,不是太庞大就是太简单,太过庞大的话不如用ui.tabs,文档和代码规范上都是可靠的因此,自制一个简洁的tabs插件还是有必要的在设计之前,先整理好思路,实现tabs,自动轮换,ajax等主要功能,然后是dom的排列形式,这里采用传统的
<div id="tabs">

<ul>

<li><a href="#tabs1">tabs1</a></li>

<li><a href="#tabs2" rel="ajax.htm">tabs2</a></li>

</ul>

<div id="tabs1">Hello World!</div>

<div id="tabs2"></div>
</div>
一个li对应一个div的方式,当ajax时,添加一个a的rel属性,并将内容写入对应的div中,再去掉rel属性,这样就只请求服务器一次,接下来都是div已经写入的内容了
我这里没有使用cookie,可以结合jquery.cookie插件,这样即使用户关闭网页下次再打开,也不用请求服务器了
一,首先写个jquery插件的闭包,园子里这两天有个朋友写了javascript的闭包概念,挺好的,有兴趣的朋友去看看

(function ($) { 
//code here 
})(jQuery);

二,插件命名,这里命名为aTabs,这样绑定的时候可以用$(...).aTabs(),本人英文名Allen,所以用a字头命名了~
$.fn.aTabs = function (options) { 
//api 
//main function 
}

三,把想好的功能写成API,供外部修改
$.fn.aTabs.defaults = { 
firstOn: 0, 
className: 'selected', 
eventName: 'all', //click,mouserover,all 
loadName: '加载中...', //ajax等待字符串 
fadeIn: 'normal', 
autoFade: false, 
autoFadeTime: 3 
}; 
var opts = $.extend({}, $.fn.aTabs.defaults, options); //这里可以将外部输入的代替掉默认的值,$.extend作用详见 <A href="http://api.jquery.com/jQuery.extend/">http://api.jquery.com/jQuery.extend/</A>,看不懂英文的直接看其中的例子就行

四,编写主体功能,说明在代码中看注释
return this.each(function () { //这里为每个绑定dom插件 
var target = $(this); 
var div = target.children().not("ul,span"); //所有的tabs显示体div 
var tabs = target.find('ul:eq(0) li'); //所有的tabs头部索引 
function Tabs() { 
if ($(this).hasClass(opts.className)) { 
return false; 
} 
tabsShow(div, $(this)); 
return false; 
} 
function tabsShow(div, li, index) { 
div.stop(true, true).hide(); 
//自动轮换用 
if (typeof (index) == "number") { 
if (li.find("a").attr("rel")) ajax(div, li); 
$(div[index]).stop(true,true).fadeIn(opts.fadeIn); 
tabs.stop(true, true).removeClass(opts.className); 
$(tabs[index]).stop(true, true).addClass(opts.className); 
} 
//非自动轮换 
else { 
var tabBody = div.filter(li.find("a").attr("href")); 
if (li.find("a").attr("rel")) ajax(div, li); 
tabBody.stop(true,true).fadeIn(opts.fadeIn); 
tabs.stop(true, true).removeClass(opts.className); 
li.stop(true, true).addClass(opts.className); 
} 
} 
function ajax(div, li) {//这里是关键ajax,通过操作rel的方式实现只请求服务器一次 
var href = li.find("a").attr("href"); 
var rel = li.find("a").attr("rel"); //ajax请求url 
var i = div.filter(href); //当前div 
if (rel) { //如果ajax请求url不为空,只ajax一次 
i.html(opts.loadName); 
$.ajax({ 
url: rel, 
cache: false, 
success: function (html) { 
i.html(html); 
}, 
error: function () { 
i.html('加载错误,请重试!'); 
} 
}); 
li.find("a").removeAttr("rel"); //只ajax一次 
} 
} 
if (opts.autoFade) { 
var index = opts.firstOn + 1; 
setInterval(function () { 
if (index >= div.length) { 
index = 0; 
} 
tabsShow(div, $(this), index++); 
}, opts.autoFadeTime * 1000); 
} 
tabs.bind(opts.eventName == 'all' ? 'click mouseover' : opts.eventName, Tabs) //绑定事件 
.filter(':first').trigger(opts.eventName == 'all' ? 'click' : opts.eventName); //自动触发事件 
});

最后,将以上整合,tabs插件就诞生了,下面是全部源码:
/* 
* 作者:黑曜石 
*/ 
(function ($) { 
$.fn.aTabs = function (options) { 
$.fn.aTabs.defaults = { 
firstOn: 0, 
className: 'selected', 
eventName: 'all', //click,mouserover,all 
loadName: '加载中...', //ajax等待字符串 
fadeIn: 'normal', 
autoFade: false, 
autoFadeTime: 3 
}; 
var opts = $.extend({}, $.fn.aTabs.defaults, options); 
return this.each(function () { 
var target = $(this); 
var div = target.children().not("ul,span"); //所有的tabs显示体div 
var tabs = target.find('ul:eq(0) li'); //所有的tabs头部索引 
function Tabs() { 
if ($(this).hasClass(opts.className)) { 
return false; 
} 
tabsShow(div, $(this)); 
return false; 
} 
function tabsShow(div, li, index) { 
div.stop(true, true).hide(); 
//自动轮换用 
if (typeof (index) == "number") { 
if (li.find("a").attr("rel")) ajax(div, li); 
$(div[index]).stop(true,true).fadeIn(opts.fadeIn); 
tabs.stop(true, true).removeClass(opts.className); 
$(tabs[index]).stop(true, true).addClass(opts.className); 
} 
//非自动轮换 
else { 
var tabBody = div.filter(li.find("a").attr("href")); 
if (li.find("a").attr("rel")) ajax(div, li); 
tabBody.stop(true,true).fadeIn(opts.fadeIn); 
tabs.stop(true, true).removeClass(opts.className); 
li.stop(true, true).addClass(opts.className); 
} 
} 
function ajax(div, li) { 
var href = li.find("a").attr("href"); 
var rel = li.find("a").attr("rel"); //ajax请求url 
var i = div.filter(href); //当前div 
if (rel) { //如果ajax请求url不为空,只ajax一次 
i.html(opts.loadName); 
$.ajax({ 
url: rel, 
cache: false, 
success: function (html) { 
i.html(html); 
}, 
error: function () { 
i.html('加载错误,请重试!'); 
} 
}); 
li.find("a").removeAttr("rel"); //只ajax一次 
} 
} 
if (opts.autoFade) { 
var index = opts.firstOn + 1; 
setInterval(function () { 
if (index >= div.length) { 
index = 0; 
} 
tabsShow(div, $(this), index++); 
}, opts.autoFadeTime * 1000); 
} 
tabs.bind(opts.eventName == 'all' ? 'click mouseover' : opts.eventName, Tabs) //绑定事件 
.filter(':first').trigger(opts.eventName == 'all' ? 'click' : opts.eventName); //自动触发事件 
}); 
}; 
})(jQuery);
Javascript 相关文章推荐
jquery一句话全选/取消全选
Mar 01 Javascript
JS中FRAME的操作问题实例分析
Oct 21 Javascript
jQuery中prevAll()方法用法实例
Jan 08 Javascript
jQuery中animate用法实例分析
Mar 09 Javascript
Angularjs中使用Filters详解
Mar 11 Javascript
package.json文件配置详解
Jun 15 Javascript
Vue.js实例方法之生命周期详解
Jul 03 Javascript
react-native android状态栏的实现
Jun 15 Javascript
利用Vue构造器创建Form组件的通用解决方法
Dec 03 Javascript
JS 封装父页面子页面交互接口的实例代码
Jun 25 Javascript
微信小程序 flexbox layout快速实现基本布局的解决方案
Mar 24 Javascript
关于vue-cli3打包代码后白屏的解决方案
Sep 02 Javascript
jQuery基础知识filter()和find()实例说明
Jul 06 #Javascript
jQuery中filter(),not(),split()使用方法
Jul 06 #Javascript
jQuery选择没有colspan属性的td的代码
Jul 06 #Javascript
jquery 查找新建元素代码
Jul 06 #Javascript
jquery 3D球状导航的文章分类
Jul 06 #Javascript
Javascript Function对象扩展之延时执行函数
Jul 06 #Javascript
JavaScript经典效果集锦
Jul 06 #Javascript
You might like
php中将时间差转换为字符串提示的实现代码
2011/08/08 PHP
PHP生成唯一订单号的方法汇总
2015/04/16 PHP
Yii开启片段缓存的方法
2016/03/28 PHP
PHP加密技术的简单实现
2016/09/04 PHP
用jscript实现列出安装的软件列表
2007/06/18 Javascript
javascript 事件处理程序介绍
2012/06/27 Javascript
JavaScript地图拖动功能SpryMap的简单实现
2013/07/17 Javascript
JS实现的Select三级下拉菜单代码
2015/08/20 Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
2016/01/18 Javascript
详解JavaScript设计模式开发中的桥接模式使用
2016/05/18 Javascript
jquery+CSS3实现3D拖拽相册效果
2016/07/18 Javascript
详解Angular.js指令中scope类型的几种特殊情况
2017/02/21 Javascript
浅析 NodeJs 的几种文件路径
2017/06/07 NodeJs
关于定制FileField中的上传文件名称问题
2017/08/22 Javascript
zTree异步加载展开第一级节点的实现方法
2017/09/05 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
React Native基础入门之调试React Native应用的一小步
2018/07/02 Javascript
highCharts提示框中显示当前时间的方法
2019/01/18 Javascript
vue element-ui之怎么封装一个自己的组件的详解
2019/05/20 Javascript
Django实现图片文字同时提交的方法
2015/05/26 Python
Python实现的计数排序算法示例
2017/11/29 Python
用Python写一个模拟qq聊天小程序的代码实例
2019/03/06 Python
Django web框架使用url path name详解
2019/04/29 Python
pandas删除行删除列增加行增加列的实现
2019/07/06 Python
python中列表的含义及用法
2020/05/26 Python
Python如何安装第三方模块
2020/05/28 Python
快速创建python 虚拟环境
2020/11/28 Python
HUGO BOSS美国官方网上商店:世界知名奢侈品牌
2017/08/04 全球购物
英国最大的LED专业零售商:Led Hut
2018/03/16 全球购物
俄罗斯园林植物网上商店:Garshinka
2020/07/16 全球购物
PHP数据运算类型都有哪些
2013/11/05 面试题
北大青鸟学生求职信
2013/09/24 职场文书
小学少先队活动方案
2014/02/18 职场文书
农村葬礼主持词
2014/03/31 职场文书
小学生十佳少年事迹材料
2014/08/20 职场文书
导游词之香港-太平山顶
2019/10/18 职场文书