开发背景
最近接了一个小型电商网站,各大商品分类都需要用到分页的技巧,虽说我只是个后台汪,但是不想搞前端的后台不是一个好开发。参考了网上的某个简单的分页插件,重新封装了下,支持ajax请求,data参数传递,分页请求回调,真的很好用呢~
最终目的
既然是开发插件,那么使用一定要简单粗暴,类似easyui datagrid这样:
$('#dg').datagrid({
url:'datagrid_data.json',
columns:[[
{field:'code',title:'Code',width:100},
{field:'name',title:'Name',width:100},
{field:'price',title:'Price',width:100,align:'right'}
]]
});
所以我大概构思了下,我的page插件应该是这样的:
$(".test").page({
'url': '/data.json',
'maxShowItem': 7,
'data': {
'limit': 6,
'attr': 'attr'
},
'currentClass': 'currentPage',
'activeClass': 'active',
'disabledClass': 'disabled',
'callback': function(currentPage, pageCount, obj){
// 处理分页内容
console.log(currentPage, pageCount, obj);
}
});
url是分页查询的请求地址,maxShowItem则是最多显示多少分页按钮,data为每次ajax请求的参数,callback即是请求成功的回调,形参为当前页码currentPage,总页数pageCount,和当前页内容(总共结果数count,单页数据集result)。
效果图示
效果图示模仿着网易云音乐做的,然后有几个关键点,我都用红线标记出来了,大概说下各个标记和重要单位的意思:
- left/right,即左右分页省略临界点;
- unit,即是currentPage两边各分布着几个分页按钮(不含首尾页);
这就是一个分页模型,当然实际开发中存在着许多条件因素,需要逐步来看。
即刻动手
这里推荐个jQuery插件编写教程的地址:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html
首先定义Page插件的构造函数:
// 定义Page的构造函数
var Page = function(ele, opt){
this.$ele = ele;
var defaults = {
// 分页ajax地址
'url': '',
// 最多展示分页按钮数
'maxShowItem': 7,
// ajax请求默认参数
'data': {
'start': 0,
'limit': 10
},
// 当前页码class名称
'currentClass': '',
// 激活的页码class名称
'activeClass': '',
// 失效的页码class名称
'disabledClass': '',
// 省略class名称
'ellipsis': '',
// 请求回调,当前页码,总页码数,当前页码内容(当页结果result,数据总数count)
'callback': null
};
this.opt = $.extend({}, defaults, opt);
};
然后拓展Page的方法:
// 定义Page的方法
Page.prototype = {
'ajax': function(currentPage){
var data = this.opt.data;
var page = this;
data.start = (currentPage - 1) * data.limit;
$.ajax({
'url': this.opt.url,
'type': 'get',
'dataType': 'json',
'data': data,
'success': function(obj){
var pageCount = Math.ceil(obj.count / data.limit);
page.resetPageItem(currentPage, pageCount);
page.opt.callback(currentPage, pageCount, obj);
},
'error': function(XMLHttpRequest, textStatus, errorThrown){
console.log(XMLHttpRequest);
console.log(textStatus);
console.log(errorThrown);
}
});
},
// 重置分页item(第一次,和每次item点击都会触发)
'resetPageItem': function(currentPage, pageCount) {
var page = this;
var pageItem = this.getPageItem(currentPage, pageCount);
this.$ele.html(pageItem);
// 为每个item绑定点击事件
this.$ele.children('a[class=\'' + this.opt.activeClass + '\']').on('click',function(){
var $this = $(this);
var currentPage = parseInt($this.attr('page-data'));
page.ajax(currentPage);
});
},
// 根据总页数和当前页数,得到分页item的html内容
'getPageItem': function(currentPage, pageCount){
var prePage = currentPage - 1;
var nextPage = currentPage + 1;
var prePageClass = this.opt.activeClass;
var nextPageClass = this.opt.activeClass;
if (prePage <= 0) {
prePageClass = this.opt.disabledClass;
}
if (nextPage > pageCount) {
nextPageClass = this.opt.disabledClass;
}
var appendStr = '';
// appendStr += '<a href=\'#\' class=\'' + prePageClass + '\' page-data=\'1\'' + '>首页</a>';
appendStr += '<a href=\'#\' class=\'' + prePageClass + '\' page-data=\''+ prePage +'\'>< 上一页</a>';
var unit = (this.opt.maxShowItem - 3) / 2;
// 左边临界
var left = currentPage - unit;
// 右边临界
var right = currentPage + unit;
if(left <= 1){
right = this.opt.maxShowItem - 1;
}
if(right >= pageCount){
left = pageCount - (this.opt.maxShowItem - 2);
}
var leftEllipsis = false;
var rightEllipsis = false;
for (var i = 1; i <= pageCount; i++) {
var itemPageClass = this.opt.activeClass;
// 左侧省略号
if(i > 1 && i < left){
if(!leftEllipsis){
itemPageClass = this.opt.ellipsis;
appendStr+='<span class=\'' + itemPageClass + '\'>...</span>';
leftEllipsis = true;
}
continue;
}
// 右侧省略号
if(i < pageCount && i > right){
if(!rightEllipsis){
itemPageClass = this.opt.ellipsis;
appendStr+='<span class=\'' + itemPageClass + '\'>...</span>';
rightEllipsis = true;
}
continue;
}
if(i == currentPage){
itemPageClass = this.opt.currentClass;
}
appendStr+='<a href=\'#\' class=\'' + itemPageClass + '\' page-data=\'' + i + '\'>' + i + '</a>';
}
appendStr += '<a href=\'#\' class=\'' + nextPageClass + '\' page-data=\'' + nextPage + '\'>下一页 ></a>';
// appendStr += '<a href=\'#\' class=\'' + nextPageClass + '\' page-data=\'' + pageCount + '\'>尾页</a>';
return appendStr;
}
};
这里要讲述下,我拓展了Page的三个方法,分别是
- ajax:点击一个active的分页按钮发起一个ajax请求,请求成功回调中初始化分页按钮items,同时调用Page构造方法参数中的callback;
- resetPageItem:通过当前页currentPage和总页数pageCount,获取分页按钮items的html内容,重置分页按钮items,同时对active的item绑定好click的ajax事件;
- getPageItem:获取分页按钮items的html内容,其实这个也可以写到resetPageItem中,只不过个人觉得生成html的逻辑有点复杂,可以和items的click绑定分开;
最后就是拓展jQuery的方法,使用Page对象:
// 在插件中使用Page对象
$.fn.page = function(opt){
var page = new Page(this, opt);
// 初次加载
page.ajax(1);
};
加上命名空间,防止变量污染:
;(function(){
// 插件代码
})(jQuery);
这样我们就编写完了整个分页控件,即可像最终目的中的那样,使用一个div的简单配置就能够一键实现ajax的分页功能,第一次自己编写呢,成就感爆棚啊~~
网友评论