效果图
需求场景
做公司后台项目,后台返回数据展示在页面展示,数据量很大,所以要采用分页,点击不同页码,ajax post当前页码以及其它必要信息给后台,返回该页码对应的数据再动态展示到页面,实现分页局部刷新。
思路
用一个div作为容器,通过配置该div的属性用js来动态生成需要的分页。在需要用到分页的地方,只需要写这样一个div标签就OK了。像这样:
<div class="test" pagination="p-new" pagenumber="5" totalnumber="15" paginationmax="10"></div>
配置的属性包括:分页的总页数、分页显示的页数、当前所在页码。分页所需要的html元素
用js动态生成,样式则采用bootstrap提供的分页的基础样式。bootstrap提供的分页的基础样式代码可以生成一个静态的分页:
<ul class="pagination">
<li><a href="#">«</a></li>
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li class="active"><a href="#">3</a></li>
<li class="disabled"><a href="#">»</a></li>
</ul>
具体实现
cdn引入jQuery和bootstrap
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
注意,jQuery一定要在bootstrap之前引入,因为bootstrap所有的js插件都依赖bootstrap
定义3个配置项变量。定义动态生成分页html结构的函数initPagination,参数传入一个dom对象,表示分页的容器。
//当前页数
var pagenumber;
//总页数
var totalnumber;
//分页栏显示的页数
var paginationmax;
paginationInit();
function initPagination(element){
pagenumber = Number(element.attr('pagenumber'));
totalnumber = Number(element.attr('totalnumber'));
paginationmax = Number(element.attr('paginationmax'));
if(totalnumber >= 1 && pagenumber <= totalnumber && paginationmax <= totalnumber){
var content =
"<ul class='pagination'>" +
"<li value='pre'>" +
"<a href='javascript:void(0);'>«</a>" +
"</li>";
for (var i = 0; i < totalnumber; i++) {
content +=
"<li value='"+ (i + 1) +"'>" +
"<a href='javascript:void(0);'>" + (i + 1) +
"</a>" +
"</li>"
}
content +=
"<li value='next'>" +
"<a href='javascript:void(0);'>»</a>" +
"</li>" +
"</ul>";
element.append(content);
// 为设置为当前页的页签添加样式
element.children('ul').children('li[value = '+ pagenumber +']').addClass('active');
element.children('ul').children('li').click(clickChange);
element.children('ul').children('li').click(processData);
// 显示那几个页签 传入任意li元素即可
pageShow(element.children('ul').children('li[value = '+ pagenumber +']'))
}else{
console.log('分页自定义属性不合理')
}
};
写一个函数用来调用上面的initPagination函数,不直接调用pagination时因为有可能一个页面需要多个分页。
// 凡是带有pagination = p-new属性的元素,都会生成分页,这样设计方便一个页面中有多个不同的分页
function paginationInit(){
$('[pagination = p-new]').each(function(){
initPagination($(this))
})
};
点击不同页签时候的样式变化。有两种情况:如果点击的是普通页签,此时点击谁就给谁对应的li添加.active样式。如果点击的是首位的上一页和下一页,那么就
需要给当前有.active的li元素的前一个或者后一个li添加.active样式。
// 点击页签时候样式的变化
function clickChange(ev){
ev = event || window.event;
pageShow($(ev.target).parent());
$(ev.target).parent().parent().children('li').each(function(index,item){
if($(item).hasClass('active')){
$(item).removeClass('active');
}
});
// 点击页码页签
if($(ev.target).parent().attr('value') != 'pre' && $(ev.target).parent().attr('value') != 'next'){
pagenumber = Number($(ev.target).parent().attr('value'))
$(ev.target).parent().addClass('active');
$(ev.target).parent().parent().children('li[value = pre]').removeClass('disabled');
$(ev.target).parent().parent().children('li[value = next]').removeClass('disabled');
// 点击上一页页签
}else if($(ev.target).parent().attr('value') == 'pre'){
pagenumber -= 1;
if(pagenumber <= 1){
pagenumber = 1;
$(ev.target).parent().parent().children('li[value = 1]').addClass('active');
$(ev.target).parent().parent().children('li[value = pre]').addClass('disabled');
}else{
$(ev.target).parent().parent().children('li[value = '+ pagenumber.toString() +']').addClass('active');
$(ev.target).parent().parent().children('li[value = pre]').removeClass('disabled');
$(ev.target).parent().parent().children('li[value = next]').removeClass('disabled');
}
// 点击下一页页签
}else if($(ev.target).parent().attr('value') == 'next'){
pagenumber += 1;
if(pagenumber >= totalnumber){
pagenumber = totalnumber;
$(ev.target).parent().parent().children('li[value = '+ totalnumber +']').addClass('active');
$(ev.target).parent().parent().children('li[value = next]').addClass('disabled');
}else{
$(ev.target).parent().parent().children('li[value = '+ pagenumber.toString() +']').addClass('active');
$(ev.target).parent().parent().children('li[value = next]').removeClass('disabled');
$(ev.target).parent().parent().children('li[value = pre]').removeClass('disabled');
}
}
}
接下来这个有点意思。展示哪些页码。比如总共100页数据,我们的分页栏始终显示10页,那么这10页就需要动态的根据当前页、总页数而变化。我是找了一个其他的分页点了点去找第几页的时候显示哪些页码这个规律的。
代码看起来有点乱,不过自己找个其他网站的分页点几下就知道怎么写了。
// 展示哪些页码 要用一个实际的分页找规律
function pageShow(element){
if(Number(pagenumber) >= 1 && Number(pagenumber) <= parseInt(.5 * Number(paginationmax))){
element.parent().children('li').each(function(index,item){
if(Number($(item).attr('value')) >= 1 + Number(paginationmax) && Number($(item).attr('value')) <= Number(totalnumber)){
$(item).css('display','none')
}else{
$(item).css('display','inline-block')
}
});
}else if(Number(pagenumber) > parseInt(.5 * Number(paginationmax)) && Number(pagenumber) <= Number(totalnumber) - parseInt(.5 * Number(paginationmax))){
element.parent().children('li').each(function(index,item){
if((Number($(item).attr('value')) >= 1 && Number($(item).attr('value')) <= Number(pagenumber) - parseInt(.5 * Number(paginationmax))) || (Number($(item).attr('value')) > Number(pagenumber) + parseInt(.5 * Number(paginationmax)) && Number($(item).attr('value')) <= Number(totalnumber))){
$(item).css('display','none')
}else{
$(item).css('display','inline-block')
}
});
}else if(Number(pagenumber) > Number(totalnumber) - parseInt(.5 * Number(paginationmax))){
element.parent().children('li').each(function(index,item){
if(Number($(item).attr('value')) >= 1 && Number($(item).attr('value')) <= Number(totalnumber) - Number(paginationmax)){
$(item).css('display','none')
}else{
$(item).css('display','inline-block')
}
});
}
}
我给每个li页签绑定了一个专门用来处理ajax的点击事件,当前所在的页码在全局可以获取到。可以处理切换页签时候发送ajax,根据不同页码返回不同数据。
// 页面切换时候的处理函数。比如发ajax根据不同页码获取不同数据展示数据等,用户自行配置。
function processData(){
console.log('当前页码',pagenumber);
// 用户在这里写页码切换时候的逻辑
}
一个简单的通用分页就完成了,引入js后只需要写一个可配置属性的div标签就可以实现bootstrap风格的动态分页。还有很多地方需要完善,比如目前变量还声明在全局等等,时间原因就先到此为止啦。
完整代码我上传到了github。https://github.com/yanhaoqi/pagination-bootstorp.git