本文详细解析了一款轻量级jQuery分页插件的开发过程。通过封装闭包结构避免全局污染,利用jQuery.extend扩展静态方法,实现了首页、尾页及动态导航按钮的渲染与交互逻辑。文章涵盖插件架构设计、参数配置及核心DOM操作,适合希望深入理解jQuery插件机制的开发者参考。
插件开发背景与效果展示
因项目需求需要一个JS分页组件,我决定自行开发。主要原因有二:一是网络上的插件代码结构往往不透明,一旦出现故障难以排查;二是现有插件功能冗余,加载无用代码会增加负担。此外,这也是练习编写jQuery插件的绝佳机会。首先展示最终效果:
http://demo.jb51.net/js/2014/EasyPage/
简要说明该插件的功能目标。
后端将查询结果全量返回,插件负责控制展示逻辑,实现分页显示。功能包括上一页、下一页、首页和尾页。当处于第一页时,隐藏首页和上一页按钮;当处于最后一页时,隐藏尾页和下一页按钮。界面仅展示部分导航按钮,点击最后一个可见按钮时,后续按钮将动态显示。
jQuery插件基础架构
接下来简述编码流程。
首先构建基础代码框架:
//为了更好的兼容性,开始前有个分号
;(
function($){//此处将$作为匿名函数的形参
}
)(jQuery)//将jQuery作为实参传递给匿名函数
这段代码利用了JavaScript的核心特性——闭包,这也是jQuery插件的标准结构。使用闭包既能防止内部临时变量污染全局命名空间,又能确保在插件内部安全地使用$作为jQuery的别名。
随后在闭包结构中编写具体方法。jQuery提供了两种扩展方式,查阅API可知:
• jQuery.extend(object) 用于扩展jQuery对象本身,即在jQuery命名空间下添加新函数。 • jQuery.fn.extend(object) 用于扩展jQuery元素集,通常用于制作插件实例方法。 从上述定义可见,jQuery.extend(object)相当于在Java或C#等语言中向jQuery添加静态方法。例如:
jQuery.extend({
"max":function(){
return max;
}
})
如此便在jQuery对象中添加了max方法,调用方式为:jQuery.max()
那么jQuery.fn是什么?查看jQuery源码可知,jQuery.fn = jQuery.prototype。因此,jQuery.fn.extend相当于在jQuery中添加成员函数。
至此应已明确两者区别:静态方法可直接调用,如jQuery.max();成员函数仅能通过jQuery实例调用,例如jQuery("#my").max()。
本例采用jQuery.extend方法,代码如下:
;(
function($){
$.extend({
"easypage":function(options){
options = $.extend({//参数设置
contentclass:"contentlist",//要显示的内容的class
navigateid:"navigatediv",//导航按钮所在的容器的id
everycount:"5",//每页显示多少个
navigatecount:"5"//导航按钮一次显示多少个
}, options);
});
其中easypage是调用分页插件的方法名,contentclass、navigateid、everycount、navigatecount为配置参数。
核心功能实现逻辑
基本框架搭建完毕后,接下来实现具体功能。
首要任务是定位分页内容并生成导航按钮,代码如下:
var currentpage = 0;//当前页
var contents = $("."+options.contentclass);//要显示的内容
var contentcount = contents.length;//得到内容的个数
var pagecount = Math.ceil(contentcount/options.everycount);//计算出页数
//拼接导航按钮
var navigatehtml = "<div id='pagefirst' class='pagefirst'><a href='javascript:void(0)'>首页</a></div><div id='pagepre' class='pagepre'><a href='javascript:void(0)'>上一页</a></div>";
for(var i = 1;i <= pagecount;i++){
navigatehtml+='<div class="pagenavigate"><a href="javascript:void(0)">'+i+'</a></div>';
}
navigatehtml+="<div id='pagenext' class='pagenext'><a href='javascript:void(0)'>下一页</a></div><div id='pagelast' class='pagelast'><a href='javascript:void(0)'>尾页</a></div>";
//加载导航按钮
$("#"+options.navigateid).html(navigatehtml)
这段代码比较简单,就不多讲。
随后实现基础交互功能,此处仅摘录部分示例:
//隐藏所有的导航按钮
$.extend({
"hidenavigates":function(){
//遍历所有的导航按钮
navigates.each(function(){
$(this).hide();
})
}
});
//显示导航按钮
$.extend({
"shownavigate":function(currentnavigate){
$.hidenavigates();
//当前按钮如果小于要求一次显示按钮个数的,从0开始显示
var begin = currentnavigate>=options.navigatecount?currentnavigate-parseInt(options.navigatecount):0;
//这里保证从第二页开始,按钮的个数都是2*options.navigatecount
if(begin>navigates.length-2*options.navigatecount){
begin = navigates.length-2*options.navigatecount;
}
//开始显示
for(var i = begin;i < currentnavigate+parseInt(options.navigatecount);i++){
$(navigates[i]).show();
}
}
});
基本代码流程如上,完整源代码见附件,具体功能实现在源码注释中已有详细说明。若对闭包仍有疑问,可参考我上一篇博客《谈谈javascript闭包》。
插件开发规范总结
最后总结jQuery插件开发的关键要点,内容摘录自《锋利的jQuery》:
• 插件文件名建议格式为jquery.[插件名].js,例如jquery.color.js • 所有对象方法应附加到jQuery.fn对象上,所有全局函数应附加到jQuery对象本身
• 在插件内部,this指向当前通过选择器获取的jQuery对象,而非像click()等方法那样指向DOM元素
• 可通过this.each遍历所有匹配元素 • 所有方法或函数插件应以分号结尾,以防压缩时出错;稳妥起见,可在插件开头也添加一个分号 • 插件应返回jQuery对象,以支持链式调用。除非插件需返回特定量(如字符串或数组) • 尽量利用闭包技巧避免变量名冲突
由于这是首次编写jQuery插件,文中可能存在疏漏,敬请谅解。