一步一步制作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 相关文章推荐
使用百度地图api实现根据地址查询经纬度
Dec 11 Javascript
原生js实现日期联动
Jan 12 Javascript
js函数内变量的作用域分析
Jan 12 Javascript
jquery实现标签上移、下移、置顶
Apr 26 Javascript
JavaScript更改字符串的大小写
May 07 Javascript
基于angularjs实现图片放大镜效果
Aug 31 Javascript
jQuery实现最简单实用的分秒倒计时
Feb 05 Javascript
详解vue-router2.0动态路由获取参数
Jun 14 Javascript
webpack搭建vue 项目的步骤
Dec 27 Javascript
在vue2.0中引用element-ui组件库的方法
Jun 21 Javascript
vue实现的请求服务器端API接口示例
May 25 Javascript
Vue中 axios delete请求参数操作
Aug 25 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 三大特点:封装,继承,多态
2017/02/19 PHP
php + nginx项目中的权限详解
2017/05/23 PHP
javascript实现的网页局布刷新效果
2008/12/01 Javascript
javascript 折半查找字符在数组中的位置(有序列表)
2010/12/09 Javascript
2014 年最热门的21款JavaScript框架推荐
2014/12/25 Javascript
fullpage.js全屏滚动插件使用实例
2016/09/06 Javascript
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
Vue如何从1.0迁移到2.0
2017/10/19 Javascript
VUE + UEditor 单图片跨域上传功能的实现方法
2018/02/08 Javascript
在vue中读取本地Json文件的方法
2018/09/06 Javascript
JavaScript设计模式之命令模式实例分析
2019/01/16 Javascript
RxJS在TypeScript中的简单使用详解
2020/04/13 Javascript
vue-router为激活的路由设置样式操作
2020/07/18 Javascript
[01:55]2014DOTA2国际邀请赛 BBC正赛第一天总结
2014/07/10 DOTA
Python Web框架Tornado运行和部署
2020/10/19 Python
Python数据结构之哈夫曼树定义与使用方法示例
2018/04/22 Python
Python3.5模块的定义、导入、优化操作图文详解
2019/04/27 Python
python代理工具mitmproxy使用指南
2019/07/04 Python
django将网络中的图片,保存成model中的ImageField的实例
2019/08/07 Python
Python模块/包/库安装的六种方法及区别
2020/02/24 Python
Tensorflow安装问题: Could not find a version that satisfies the requirement tensorflow
2020/04/20 Python
css3实现的多级渐变下拉菜单导航效果代码
2015/08/31 HTML / CSS
澳大利亚儿童鞋在线:The Trybe
2019/07/16 全球购物
Groupon比利时官方网站:特卖和网上购物高达-70%
2019/08/09 全球购物
说说你所熟悉或听说过的j2ee中的几种常用模式?及对设计模式的一些看法
2012/05/24 面试题
最新茶叶店创业计划书
2014/01/14 职场文书
仓管岗位职责范本
2014/02/08 职场文书
借款担保书范文
2014/05/13 职场文书
英文求职信范文
2014/05/23 职场文书
企业授权委托书范本
2014/09/22 职场文书
捐款仪式主持词
2015/07/04 职场文书
爱国教育主题班会
2015/08/14 职场文书
2016年感恩教师节校园广播稿
2015/12/18 职场文书
python自然语言处理之字典树知识总结
2021/04/25 Python
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
2022/04/11 Vue.js
CentOS7安装GlusterFS集群以及相关配置
2022/04/12 Servers