面向对象封装分页代码

时间:2021-07-26 21:57:19

首先 看下关键的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. 接口调成功以后页面数据的渲染