一步一步制作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图片播放8款精美插件分享
Feb 17 Javascript
使用jQuery同时控制四张图片的伸缩实现代码
Apr 19 Javascript
扩展IE中一些不兼容的方法如contains、startWith等等
Jan 09 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
Mar 10 Javascript
JavaScript Date对象详解
Mar 01 Javascript
详解Javascript中prototype属性(推荐)
Sep 03 Javascript
微信小程序实现瀑布流布局与无限加载的方法详解
May 12 Javascript
mongoose更新对象的两种方法示例比较
Dec 19 Javascript
简单谈谈CommonsChunkPlugin抽取公共模块
Dec 31 Javascript
Vue 项目中遇到的跨域问题及解决方法(后台php)
Mar 28 Javascript
vue-router3.0版本中 router.push 不能刷新页面的问题
May 10 Javascript
解决Mac安装thrift因bison报错的问题
May 17 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
一个MYSQL操作类
2006/11/16 PHP
php 下载保存文件保存到本地的两种实现方法
2013/08/12 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
php表单文件iframe异步上传实例讲解
2017/07/26 PHP
PHP递归实现快速排序的方法示例
2017/12/18 PHP
html的DOM中Event对象onblur事件用法实例
2015/01/21 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
2015/11/29 Javascript
JavaScript中rem布局在react中的应用
2015/12/09 Javascript
Javascript基础之数组的使用
2016/05/13 Javascript
jQuery mobile在页面加载时添加加载中效果 document.ready 和window.onload执行顺序比较
2016/07/14 Javascript
深入理解(function(){... })();
2016/08/16 Javascript
JS去除字符串中空格的方法
2017/02/14 Javascript
layer弹窗插件操作方法详解
2017/05/19 Javascript
浅谈vue中改elementUI默认样式引发的static与assets的区别
2018/02/03 Javascript
Vuex实现计数器以及列表展示效果
2018/03/10 Javascript
vue+element-ui动态生成多级表头的方法
2018/08/28 Javascript
Element-ui tree组件自定义节点使用方法代码详解
2018/09/17 Javascript
element-ui 本地化使用教程详解
2019/10/28 Javascript
vue获取form表单的值示例
2019/10/29 Javascript
vue中实现动态生成二维码的方法
2020/02/21 Javascript
js实现星星打分效果
2020/07/05 Javascript
Python logging模块学习笔记
2014/05/24 Python
python开发之for循环操作实例详解
2015/11/12 Python
Python 数据结构之旋转链表
2017/02/25 Python
django项目登录中使用图片验证码的实现方法
2019/08/15 Python
pytorch实现对输入超过三通道的数据进行训练
2020/01/15 Python
英国二手物品交易网站:Preloved
2017/10/06 全球购物
机电一体化自荐信
2013/12/10 职场文书
英文商务邀请信
2014/01/22 职场文书
村道德模范事迹材料
2014/08/28 职场文书
中学生旷课检讨书模板
2014/10/08 职场文书
2014年学校德育工作总结
2014/12/05 职场文书
大学同学聚会感言
2015/07/30 职场文书
2019初中学生入团申请书
2019/06/27 职场文书
Html5新增了哪些功能
2021/04/16 HTML / CSS
十大必看国产动漫排名,魁拔上线,第二曾在日本播出
2022/03/18 国漫