面向对象封装分页代码
首先 看下关键的api,
var DEFAULTS = {
defaultIndex: 1, //默认页
defaultSize: 10, //默认分页大小
pageIndexName: 'page', //分页参数名称
pageSizeName: 'page_size', //分页大小参数名称
onChange: '', //分页改变或分页大小改变时的回调
onInit: '', //初始化完毕的回调
allowActiveClick: true, //控制当前页是否允许重复点击刷新
middlePageItems: 4, //中间连续部分显示的分页项
frontPageItems: 3, //分页起始部分最多显示3个分页项,否则就会出现省略分页项
backPageItems: 2, //分页结束部分最多显示2个分页项,否则就会出现省略分页项
ellipseText: '...', //中间省略部分的文本
prevText: '上一页',
nextText: '下一页',
prevDisplay: true, //是否显示上一页按钮
nextDisplay: true, //是否显示下一页按钮
firstText: '首页',
lastText: '尾页',
firstDisplay: false, //是否显示首页按钮
lastDisplay: false //是否显示尾页按钮
};
对于$.extend({},{})扩展对象,这里用原生的 方法实现的,代码如下:
function cloneObj(oldObj) { //复制对象方法
if (typeof(oldObj) != 'object') return oldObj;
if (oldObj == null) return oldObj;
var newObj = new Object();
for (var i in oldObj)
newObj[i] = cloneObj(oldObj[i]);
return newObj;
};
function extendObj() { //扩展对象
var args = arguments;
if (args.length < 2) return;
var temp = cloneObj(args[0]); //调用复制对象方法
for (var n = 1; n < args.length; n++) {
for (var i in args[n]) {
temp[i] = args[n][i];
}
}
return temp;
}
用法为:
var t = extendObj(o1, o2, o3);
具体js文件main.js如下:
var DEFAULTS = { defaultIndex: 1, //默认页 defaultSize: 10, //默认分页大小 pageIndexName: 'page', //分页参数名称 pageSizeName: 'page_size', //分页大小参数名称 onChange: '', //分页改变或分页大小改变时的回调 onInit: '', //初始化完毕的回调 allowActiveClick: true, //控制当前页是否允许重复点击刷新 middlePageItems: 4, //中间连续部分显示的分页项 frontPageItems: 3, //分页起始部分最多显示3个分页项,否则就会出现省略分页项 backPageItems: 2, //分页结束部分最多显示2个分页项,否则就会出现省略分页项 ellipseText: '...', //中间省略部分的文本 prevText: '上一页', nextText: '下一页', prevDisplay: true, //是否显示上一页按钮 nextDisplay: true, //是否显示下一页按钮 firstText: '首页', lastText: '尾页', firstDisplay: false, //是否显示首页按钮 lastDisplay: false //是否显示尾页按钮 }; function cloneObj(oldObj) { //复制对象方法 if (typeof(oldObj) != 'object') return oldObj; if (oldObj == null) return oldObj; var newObj = new Object(); for (var i in oldObj) newObj[i] = cloneObj(oldObj[i]); return newObj; }; function extendObj() { //扩展对象 var args = arguments; if (args.length < 2) return; var temp = cloneObj(args[0]); //调用复制对象方法 for (var n = 1; n < args.length; n++) { for (var i in args[n]) { temp[i] = args[n][i]; } } return temp; } /** * 获取连续部分的起止索引 */ function getInterval(data, opts) { var ne_half = Math.ceil(opts.middlePageItems / 2); var np = data.pages; var upper_limit = np - opts.middlePageItems; var start = data.pageIndex > ne_half ? Math.max(Math.min(data.pageIndex - ne_half, upper_limit), 0) : 0; var end = data.pageIndex > ne_half ? Math.min(data.pageIndex + ne_half, np) : Math.min(opts.middlePageItems, np); return [start, end]; } function PageView(element, pageInfo) { this.options = extendObj(DEFAULTS, pageInfo); this.element = $(element); this.pageIndex = this.options.defaultIndex; this.pageSize = this.options.defaultSize; } PageView.prototype = { init: function() { var opts = this.options; var $element = this.element; if (typeof(opts.onChange) === 'function') { $element.on('pageViewChange', $.proxy(opts.onChange, this)) } if (typeof(opts.onInit) === 'function') { $element.on('pageViewInit', $.proxy(opts.onInit, this)); } //子类可在这里面处理分页点击及分页大小改变的事件 this.bindEvents(); $element.trigger('pageViewInit'); }, //获取分页参数 getParams: function() { var p = {}; p[this.options.pageIndexName] = this.pageIndex; p[this.options.pageSizeName] = this.pageSize; return p; }, //传递一个记录总数来刷新分页状态 refresh: function(total) { this._setup(total); this.render(); }, _setup: function(total) { //分页信息对象,可用于渲染UI var data = this.data = {}; //当前页 var pageIndex = data.pageIndex = this.pageIndex; //分页大小 var pageSize = data.pageSize = this.pageSize; //总记录数 data.total = total; //总页数 var pages = data.pages = parseInt(Math.floor(total == 0 ? 1 : ((total % pageSize) == 0 ? total / pageSize : (total / pageSize + 1)))); //当前页的记录范围 data.start = total == 0 ? 0 : ((pageIndex - 1) * pageSize + 1); data.end = total == 0 ? 0 : (pageIndex == pages) ? total : pageSize * pageIndex; //是否为第一页,是否为最后一页 data.first = pageIndex == 1; data.last = pageIndex == pages; }, //子类需覆盖此方法,呈现分页UI render: function() { var data = this.data, opts = this.options; var html = []; //首页 opts.firstDisplay && html.push([ '<li class="first ', data.first ? 'disabled' : '', '"><a href="javascript:;">', opts.firstText, '</a></li>' ].join('')); //上一页 opts.prevDisplay && html.push([ '<li class="prev ', data.first ? 'disabled' : '', '"><a href="javascript:;">', opts.prevText, '</a></li>' ].join('')); function appendItem(page) { page = page + 1; html.push([ '<li class="page ', page == data.pageIndex ? 'active' : '', '"><a href="javascript:;">', page, '</a></li>', ].join('')); } function appendEllItem() { html.push([ '<li class="page page_ell', '"><span>', opts.ellipseText, '</span></li>', ].join('')); } var interval = getInterval(data, opts); // 产生起始点 if (interval[0] > 0 && opts.frontPageItems > 0) { var end = Math.min(opts.frontPageItems, interval[0]); for (var i = 0; i < end; i++) { appendItem(i); } if (opts.frontPageItems < interval[0] && opts.ellipseText) { appendEllItem(); } } // 产生内部的些链接 for (var i = interval[0]; i < interval[1]; i++) { appendItem(i); } // 产生结束点 if (interval[1] < data.pages && opts.backPageItems > 0) { if (data.pages - opts.backPageItems > interval[1] && opts.ellipseText) { appendEllItem(); } var begin = Math.max(data.pages - opts.backPageItems, interval[1]); for (var i = begin; i < data.pages; i++) { appendItem(i); } } //下一页 opts.nextDisplay && html.push([ '<li class="next ', data.last ? 'disabled' : '', '"><a href="javascript:;">', opts.nextText, '</a></li>' ].join('')); //尾页 opts.lastDisplay && html.push([ '<li class="last ', data.last ? 'disabled' : '', '"><a href="javascript:;">', opts.lastText, '</a></li>' ].join('')); this.element.html(html.join('')); }, bindEvents: function() { var that = this, opts = this.options, $element = this.element; function pageIndexChange(pageIndex) { if (that.disabled) return; that.pageIndex = pageIndex; $element.trigger('pageViewChange'); } //首页 opts.firstDisplay && $element.on('click', '.first:not(.disabled) a', function(e) { e.preventDefault(); pageIndexChange(1); }); //末页 opts.lastDisplay && $element.on('click', '.last:not(.disabled) a', function(e) { e.preventDefault(); pageIndexChange(that.data.pages); }); //上一页 opts.prevDisplay && $element.on('click', '.prev:not(.disabled) a', function(e) { e.preventDefault(); pageIndexChange(that.pageIndex - 1); }); //下一页 opts.nextDisplay && $element.on('click', '.next:not(.disabled) a', function(e) { e.preventDefault(); pageIndexChange(that.pageIndex + 1); }); //具体页 $element.on('click', '.page a', function(e) { e.preventDefault(); var $this = $(this), callback = true; if ($this.parent().hasClass('active') && !opts.allowActiveClick) { callback = false; } callback && pageIndexChange(parseInt($.trim($this.text()))); }); }, //启用 enable: function() { this.disabled = false; this.element.removeClass('disabled'); }, //禁用 disable: function() { this.disabled = true; this.element.addClass('disabled'); } };
HTML如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Examples</title> <meta name="description" content="test"> <meta name="keywords" content="test"> <link href="css/page.css" rel="stylesheet" > <script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="js/main.js"> </script> <script type="text/javascript"> $(function() { var api = { list: 'http://liuyunzhuge.github.io/blog/form/dist/html/api/pageView.json', }; var getBlogItemHtml = function (row) { return ['<li class="blog-entry">', ' <div class="cell pl15">', ' <h3 class="f14 mb5 lh18"><a href="#" class="blog-title">', row.title, '</a></h3>', ' <p class="pt5 mb5 lh24 g3 fix">', ' <img src="', row.avatar, '" alt="" class="bdc p1 w50 h50 l mr5">', row.content, '</p>', ' <p class="mt10 lh20"><a href="#" class="blog-author">', row.author, '</a><span class="dib ml15 mr15">发布于 ', row.publish_time, '</span><a', ' href="#" class="blog-stas">评论(', row.comment, ')</a><a href="#" class="blog-stas">阅读(', row.read, ')</a></p>', ' </div>', '</li>'].join(''); }, getData = function () { pageView.disable(); $.ajax({ url: api.list, type:'GET', data:pageView.getParams() }).done(function (res) { if (res.code == 200) { var html = []; pageView.refresh(res.data.total); res.data.rows.forEach(function (row, i) { row.title = row.title + (pageView.data.start + i); html.push(getBlogItemHtml(row, i)); }); $blog_list.html(html.join('')); } }).always(function(){ pageView.enable(); }); }, $blog_list = $('#blog_list'), pageView = new PageView('#page_view', { defaultSize: 10, firstDisplay:true, lastDisplay:true, onChange: getData }); pageView.init(); getData(); }); </script> <body> <div id="blog_list"></div> <ul id="page_view" class="page_view"> <!-- <li class="page "><a href="javascript:;">1</a></li> --> </ul> </body> </html>
page.css代码如下:
a { text-decoration: none; } .page_wrapper { padding-top: 20px; padding-bottom: 20px; } .page_wrapper .page_view { text-align: center; } .page_view { padding: 0; margin: 0; } .page_view:before, .page_view:after { content: " "; display: table; } .page_view:after { clear: both; } .page_view > li { display: inline-block; } .page_view > li + li { margin-left: 10px; } .page_view > li > a, .page_view > li > span { display: block; line-height: 28px; height: 28px; text-align: center; color: #646464; border-radius: 14px; background-color: transparent; border: 1px solid #d1ced1; font-size: 12px; width: 28px; font-weight: 400; } .page_view > li > a:hover,.page_view > li > a:focus { text-decoration: none; } .page_view:not(.disabled) > li:not(.disabled) > a:hover, .page_view > li.active > a { color: #fff; background-color: #06af79; border-color: #06af79; } .page_view > li.disabled, .disabled.page_view > li { opacity: .7; } .page_view > li.disabled > a:hover, .disabled.page_view > li > a:hover { cursor: not-allowed; } .page_view > li.page_ell { vertical-align: top; } .page_view > li.page_ell > span { line-height: 18px; } .page_view > li.prev > a, .page_view > li.next > a, .page_view > li.first > a, .page_view > li.last > a { width: auto; padding: 0 11px; }
// 用法:
// 1. 首先定义渲染页面的dom标签,比如这里的id="page_view"
// 2. 定义默认的属性,这里
// {
// defaultSize: 10,
// onChange: getData
// }
// 3. 实例化PageView,如:
// pageView = new PageView('#page_view', {
// defaultSize: 10,
// onChange: getData
// })
// 4. 定义getData函数,通过调接口并传参,注意接口的参数通过pageView.getParams()获取,所以根据需要设定接口的传参
// pageIndexName: 'page', //分页参数名称
// pageSizeName: 'page_size', //分页大小参数名称
// 可以根据需要修改
// 5. 接口调成功以后页面数据的渲染