之前我在自己的博客里发表了一篇用angularJs自定义指令实现的分页插件,今天简单改造了一下,改成了原生JavaScript版本的分页插件,可以自定义一些简单配置,特此记录下来。如有不足之处,欢迎指出。
本插件可以自定义的功能:
1. 可初始化每页条数,以及重新选择每页条数
2.自定义首末页、上下页按钮的显示内容(是:<<、 >>、 < 、 > 还是:首页、末页、上一页、下一页)
3.设置当前页在一定范围时,是否显示省略号按钮
4.自定义当前页按钮与省略号按钮之间显示的数字按钮的个数
需要设置的参数如下:
pageSize: 10, //每页条数(不设置时,默认为10) prevPage: '上页', //上一页按钮显示内容(不设置时,默认为:<) nextPage: '下页', //下一页按钮显示内容(不设置时,默认为:>) firstPage: '首页', //首页按钮显示内容(不设置时,默认为:<<) lastPage: '末页', //末页按钮显示内容(不设置时,默认为:>>) degeCount: 4, //当前页前后两边可显示的页码个数(不设置时,默认为3) ellipsis: true //是否显示省略号按钮(不可点击)(true:显示,false:不显示,不设置时,默认为显示)
这些设置项只需要在页面加载时定义一个js对象,设置相应的参数,在创建Paging实例时,传入该对象即可。当然也可以不定义该参数对象,则在创建Paging实例时,需传入空对象,此时就是默认设置。
由于本案例用ajax调用的接口是真实接口,返回的都是真实数据,所以在本博客的代码中,我会把调用的接口地址和相关的请求头信息隐藏。
自己实现的简单小插件,把分页部分的css样式写在了插件paging.js中,以动态创建style标签的方式,加入到页面中。
分页的css样式写在插件中,动态创建style标签,加载到页面中。在该js中有一个Paging构造函数。在构造函数中有两个参数,第一个是自定义分页参数的js对象,第二个是回调函数。
在构造函数中有一个initPage()方法。用来渲染分页DOM结构。页码点击事件和选择每页条数的事件都写在构造函数中,目前这样感觉确实不好,后续再改进。
代码如下:
var tableStyle =
".page {font-size: 14px;background-color: transparent;width: 100%;height: 50px;line-height: 50px;display: none;}"+
".page .page-l select {width: 60px;height: 30px;}"+
".page .page-l .page-size-box {display: inline-block;margin-left: 20px;}"+
".page .page-r {float: right;padding-top: 10px;}"+
".page .page-r ul {float: left;list-style: none;margin: 0;height: 30px;box-sizing: border-box;padding: 0;}"+
".page .page-r ul li {float: left;list-style: none;height: 100%;line-height: 30px;border: 1px solid #ccc;border-right: 0 none;box-sizing: border-box;}"+
".page .page-r ul li a:hover {background-color: #f5f2f2;}"+
".page .page-r ul li:last-child {border-right: 1px solid #ccc;}"+
".page .page-r ul li a {text-decoration: none;display: block;height: 100%;padding:0 10px; color: #777;}"+
".page .page-r ul li a.active {background-color: #09aeb0;color: #fff;}"+
".page .page-r ul li span {display: block;height: 100%;padding:0 10px;color: #ccc;cursor: not-allowed;}"+
".page .page-r ul li span.ellipsis {cursor: default;}";
var styleNode = document.createElement('style');
styleNode.innerHTML = tableStyle;
var headNode = document.getElementsByTagName('head')[0];
headNode.appendChild(styleNode);
function Paging(paramsObj, callback) {
this.pageSize = paramsObj.pageSize || 10; //每页条数(不设置时,默认为10
this.pageIndex = paramsObj.pageIndex || 1; //当前页码
this.totalCount = paramsObj.totalCount || 0; //总记录数
this.totalPage = Math.ceil(paramsObj.totalCount / paramsObj.pageSize) || 0; //总页数
this.prevPage = paramsObj.prevPage || '<'; //上一页(不设置时,默认为:<)
this.nextPage = paramsObj.nextPage || '>'; //下一页(不设置时,默认为:>)
this.firstPage = paramsObj.firstPage || '<<'; //首页(不设置时,默认为:<<)
this.lastPage = paramsObj.lastPage || '>>'; //末页(不设置时,默认为:>>)
this.degeCount = paramsObj.degeCount || 3; //当前页前后两边可显示的页码个数(不设置时,默认为3)
this.ellipsis = paramsObj.ellipsis; //是否显示省略号不可点击按钮(true:显示,false:不显示)
this.ellipsisBtn = (paramsObj.ellipsis == true || paramsObj.ellipsis == null) ? '<li><span class="ellipsis">…</span></li>' : '';
var that = this;
$('#page_size').val(this.pageSize);
callback && callback(this.pageIndex, this.pageSize); //立即执行回调函数
// 生成分页DOM结构
this.initPage = function (totalCount, totalPage, pageIndex) {
this.totalCount = totalCount;
this.totalPage = totalPage;
this.pageIndex = pageIndex;
var degeCount = this.degeCount;
var pageHtml = ''; //总的DOM结构
var tmpHtmlPrev = ''; //省略号按钮前面的DOM
var tmpHtmlNext = ''; //省略号按钮后面的DOM
var headHtml = ''; //首页和上一页按钮的DOM
var endHtml = ''; //末页和下一页按钮的DOM
if(pageIndex - degeCount >= degeCount-1 && totalPage - pageIndex >= degeCount+1){ //前后都需要省略号按钮
headHtml = '<li><a id="first_page" href="javascript:;">'+this.firstPage+'</a></li>'+
'<li><a id="prev_page" href="javascript:;">'+this.prevPage+'</a></li>';
endHtml = '<li><a id="next_page" href="javascript:;">'+this.nextPage+'</a></li>'+
'<li><a id="last_page" href="javascript:;">'+this.lastPage+'</a></li>';
var count = degeCount; //前后各自需要显示的页码个数
for(var i=0; i<count; i++){
if(pageIndex != 1){
tmpHtmlPrev += '<li><a href="javascript:;" class="page-number">'+(pageIndex-(count-i))+'</a></li>';
}
tmpHtmlNext += '<li><a href="javascript:;" class="page-number">'+((pageIndex-0)+i+1)+'</a></li>';
}
pageHtml = headHtml +
this.ellipsisBtn +
tmpHtmlPrev +
'<li><a href="javascript:;" class="active">'+pageIndex+'</a></li>'+
tmpHtmlNext +
this.ellipsisBtn +
endHtml;
}else if(pageIndex - degeCount >= degeCount-1 && totalPage - pageIndex < degeCount+1) { //前面需要省略号按钮,后面不需要
headHtml = '<li><a id="first_page" href="javascript:;">'+this.firstPage+'</a></li>'+
'<li><a id="prev_page" href="javascript:;">'+this.prevPage+'</a></li>';
if(pageIndex == totalPage){ //如果当前页就是最后一页
endHtml = '<li><span id="next_page" href="javascript:;">'+this.nextPage+'</span></li>'+
'<li><span id="last_page" href="javascript:;">'+this.lastPage+'</span></li>';
}else{ //当前页不是最后一页
endHtml = '<li><a id="next_page" href="javascript:;">'+this.nextPage+'</a></li>'+
'<li><a id="last_page" href="javascript:;">'+this.lastPage+'</a></li>';
}
var count = degeCount; //前需要显示的页码个数
var countNext = totalPage - pageIndex; //后需要显示的页码个数
if(pageIndex != 1){
for(var i=0; i<count; i++){
tmpHtmlPrev += '<li><a href="javascript:;" class="page-number">'+(pageIndex-(count-i))+'</a></li>';
}
}
for(var i=0; i<countNext; i++){
tmpHtmlNext += '<li><a href="javascript:;" class="page-number">'+((pageIndex-0)+i+1)+'</a></li>';
}
pageHtml = headHtml +
this.ellipsisBtn +
tmpHtmlPrev +
'<li><a href="javascript:;" class="active">'+pageIndex+'</a></li>'+
tmpHtmlNext +
endHtml;
}else if(pageIndex - degeCount < degeCount-1 && totalPage - pageIndex >= degeCount+1){ //前面不需要,后面需要省略号按钮
if(pageIndex == 1){ //如果当前页就是第一页
headHtml = '<li><span id="first_page" href="javascript:;">'+this.firstPage+'</span></li>'+
'<li><span id="prev_page" href="javascript:;">'+this.prevPage+'</span></li>';
}else{ //当前页不是第一页
headHtml = '<li><a id="first_page" href="javascript:;">'+this.firstPage+'</a></li>'+
'<li><a id="prev_page" href="javascript:;">'+this.prevPage+'</a></li>';
}
endHtml = '<li><a id="next_page" href="javascript:;">'+this.nextPage+'</a></li>'+
'<li><a id="last_page" href="javascript:;">'+this.lastPage+'</a></li>';
var countPrev = pageIndex - 1; //前需要显示的页码个数
var count = degeCount; //后需要显示的页码个数
if(pageIndex != 1){
for(var i=0; i<countPrev; i++){
tmpHtmlPrev += '<li><a href="javascript:;" class="page-number">'+(pageIndex-(countPrev-i))+'</a></li>';
}
}
for(var i=0; i<count; i++){
tmpHtmlNext += '<li><a href="javascript:;" class="page-number">'+((pageIndex-0)+i+1)+'</a></li>';
}
pageHtml = headHtml +
tmpHtmlPrev +
'<li><a href="javascript:;" class="active">'+pageIndex+'</a></li>'+
tmpHtmlNext +
this.ellipsisBtn +
endHtml;
}else if(pageIndex - degeCount < degeCount-1 && totalPage - pageIndex < degeCount+1){ //前后都不需要省略号按钮
headHtml = '<li><a id="first_page" href="javascript:;">'+this.firstPage+'</a></li>'+
'<li><a id="prev_page" href="javascript:;">'+this.prevPage+'</a></li>';
endHtml = '<li><a id="next_page" href="javascript:;">'+this.nextPage+'</a></li>'+
'<li><a id="last_page" href="javascript:;">'+this.lastPage+'</a></li>';
if(totalPage == 1){ //如果总页数就为1
headHtml = '<li><span id="first_page" href="javascript:;">'+this.firstPage+'</span></li>'+
'<li><span id="prev_page" href="javascript:;">'+this.prevPage+'</span></li>';
endHtml = '<li><span id="next_page" href="javascript:;">'+this.nextPage+'</span></li>'+
'<li><span id="last_page" href="javascript:;">'+this.lastPage+'</span></li>';
}else{
if(pageIndex == 1){ //如果当前页就是第一页
headHtml = '<li><span id="first_page" href="javascript:;">'+this.firstPage+'</span></li>'+
'<li><span id="prev_page" href="javascript:;">'+this.prevPage+'</span></li>';
endHtml = '<li><a id="next_page" href="javascript:;">'+this.nextPage+'</a></li>'+
'<li><a id="last_page" href="javascript:;">'+this.lastPage+'</a></li>';
}else if(pageIndex == totalPage){ //如果当前页是最后一页
headHtml = '<li><a id="first_page" href="javascript:;">'+this.firstPage+'</a></li>'+
'<li><a id="prev_page" href="javascript:;">'+this.prevPage+'</a></li>';
endHtml = '<li><span id="next_page" href="javascript:;">'+this.nextPage+'</span></li>'+
'<li><span id="last_page" href="javascript:;">'+this.lastPage+'</span></li>';
}
}
var countPrev = pageIndex - 1; //前需要显示的页码个数
var countNext = totalPage - pageIndex; //后需要显示的页码个数
if(pageIndex != 1){
for(var i=0; i<countPrev; i++){
tmpHtmlPrev += '<li><a href="javascript:;" class="page-number">'+(pageIndex-(countPrev-i))+'</a></li>';
}
}
for(var i=0; i<countNext; i++){
tmpHtmlNext += '<li><a href="javascript:;" class="page-number">'+((pageIndex-0)+i+1)+'</a></li>';
}
pageHtml = headHtml +
tmpHtmlPrev +
'<li><a href="javascript:;" class="active">'+pageIndex+'</a></li>'+
tmpHtmlNext +
endHtml;
}
$('#page_ul').html(pageHtml);
$('#total_count').html(totalCount);
};
// 点击页码(首页、上一页、下一页、末页、数字页)
$('#page_ul').on('click','a',function (e) {
var _this = $(this);
var idAttr = _this.attr('id');
var className = _this.attr('class');
if(idAttr == 'first_page'){ //如果是点击的首页
that.pageIndex = 1;
}else if(idAttr == 'prev_page'){ //如果点击的是上一页
that.pageIndex = that.pageIndex == 1 ? that.pageIndex : that.pageIndex - 1 ;
}else if(idAttr == 'next_page'){ //如果点击的是下一页
that.pageIndex = that.pageIndex == that.totalPage ? that.pageIndex : parseInt(that.pageIndex) + 1;
}else if(idAttr == 'last_page'){ //如果点击的是末页
that.pageIndex = that.totalPage;
}else if(className == 'page-number'){ //如果点击的是数字页码
that.pageIndex = _this.html();
}
callback && callback(that.pageIndex, that.pageSize);
});
// 改变每页条数
$('#page_size').change(function () {
var _this = $(this);
that.pageIndex = paramsObj.pageIndex = 1;
that.pageSize = paramsObj.pageSize = _this.val() - 0;
callback && callback(that.pageIndex, that.pageSize);
})
}
只需要在创建Paging实例的时候,传入设置项的js对象,然后在回调函数里发送ajax请求获取数据。回调函数里需要传入两个形参,依次是当前页码和每页条数。ajax请求的成功回调里根据接口返回的总条数,结合每页条数计算出总页数。再调用Paging实例的initPage()方法,传入总条数、总页数和当前页码,即可渲染出分页的DOM结构了。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js版分页插件</title>
<style>
.data {
width: 70%;
margin: 0 auto;
}
.params {
margin: 20px 0;
}
.params input {
height: 30px;
box-sizing: border-box;
}
.params .search-btn {
float: right;
width: 80px;
border: 0 none;
background-color: #666;
color: #fff;
font-size: 14px;
}
table {
width: 100%;
border-collapse: collapse;
text-align: center;
}
th, td {
border: 1px solid #999;
height: 26px;
line-height: 26px;
}
.no-data {
display: none;
height: 80px;
line-height: 80px;
text-align: center;
color: #aaa;
}
</style>
</head>
<body>
<div class="data">
<div class="params">
<label for="course_id">用户姓名:</label><input type="text" id="user_name">
<input type="button" value="查询" class="search-btn" id="search_btn">
</div>
<table>
<thead>
<tr>
<th>序号</th>
<th>用户ID</th>
<th>姓名</th>
<th>创建时间</th>
</tr>
</thead>
<tbody id="data_list"></tbody>
</table>
<div class="no-data">未查询到数据</div>
<!-- 分页结构 -->
<div class="page">
<div class="page-l" id="page_l" style="float: left;">
<span>总共 <span id="total_count"></span> 条</span>
<div class="page-size-box">
<span>每页显示</span>
<select id="page_size">
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
<option value="100">100</option>
</select>条
</div>
</div>
<div class="page-r">
<ul id="page_ul" class="page-ul"></ul>
</div>
</div>
</div>
<script src="../lib/jquery.js"></script>
<script src="paging-bak.js"></script>
<script>
$(function () {
//分页参数(参数名固定不可变)
var pageConfig = {
pageSize: 10, //每页条数(不设置时,默认为10)
prevPage: '上页', //上一页(不设置时,默认为:<)
nextPage: '下页', //下一页(不设置时,默认为:>)
firstPage: '首页', //首页(不设置时,默认为:<<)
lastPage: '末页', //末页(不设置时,默认为:>>)
degeCount: 4, //当前页前后两边可显示的页码个数(不设置时,默认为3)
ellipsis: true //是否显示省略号按钮(不可点击)(true:显示,false:不显示,不设置时,默认为显示)
}
getList(); //初始加载就查询
//点击查询按钮
$('#search_btn').click(function () {
getList();
})
//查询列表数据
function getList() {
//初始化Paging实例(pageConfig参数也可以为空对象,此时就是默认设置)
var pageIng = new Paging(pageConfig, function (pageIndex, pageSize) {
var userName = $('#user_name').val();
$.ajax({
url:'http://******/getSysUserList.do', //这里就不显示接口地址
type:'get',
data:{
pageIndex: pageIndex,
pageSize: pageSize,
name: userName
},
success: function (res) {
if(res.success == 1){
if(res.data.length > 0){ //如果查询到了数据
var dataList = res.data;
var html = '';
dataList.forEach(function (item, i) {
html += '<tr>'+
'<td style="width: 20%;">'+((pageIndex-1)*pageSize+i+1)+'</td>'+
'<td style="width: 20%;">'+item.id+'</td>'+
'<td style="width: 30%;">'+item.name+'</td>'+
'<td style="width: 30%;">'+item.createTime+'</td>'+
'</tr>';
});
$('#data_list').html(html);
var totalCount = res.totalCount; //接口返回的总条数
var totalPage = Math.ceil(totalCount / pageSize); //根据总条数和每页条数计算总页码数
// 调用Paging实例的 initPage()方法生成分页DOM结构
pageIng.initPage(totalCount, totalPage, pageIndex);
$('.page').show();
$('.no-data').hide();
}else{ //如果未查询到数据
$('#data_list').html('');
$('.page').hide();
$('.no-data').show();
}
}else{
$('#data_list').html('');
$('.page').hide();
$('.no-data').show();
}
}
})
});
}
})
</script>
</body>
</html>
当前显示第一页时,首页和上页按钮不可点击,鼠标移上去时,也会显示不可点击的状态
由于初始化的degeCount参数为4,ellipsis参数为true,所以当当前页在一定范围时,会出现省略号按钮,在当前页按钮的两边会显示4个可点击的按钮
如果当前页是最后一页,则末页和下页的按钮不可点击,鼠标移上去时,会显示不可点击的状态
当修改每页显示条数时,会自动重新查询数据,默认显示第一页
当查询结果的总页数为1的时候,则首页、上页、下页、末页四个按钮均不可点击