開發(fā)中難免要碰到分頁查詢的功能實現(xiàn). 這個功能個人是比較頭疼, (1)雖然功能簡單, 但實現(xiàn)的嚴(yán)謹還是比較費神的. (2)不能環(huán)境下, 一樣的分頁代碼難以滿足, 比如html中和jsp中就不一樣. 同步請求和異步請求有不一樣.
對于一些用于jsp環(huán)境的分頁套路, 個人不是很喜歡, 沒辦法, 鐘愛前后端分離的套路. 于是想找一款基于js的實現(xiàn)的分頁條功能. 無意中發(fā)現(xiàn)下面將要介紹的這款插件. 基本功能完全沒有問題. 但是想要滿足自己的定制化需求還是比較費勁的. 我想這也是前端的通病吧, 變幻莫測. 根本難以一套代碼搞定一切場景.
jquery.pagination.js
這一款比較好用前端分頁jquery插件.
GitHub地址
demo


缺陷
- 作者的初衷設(shè)計是想要樣式和功能分離. 這樣還是不錯的, 留給使用充分的定制空間. 然而, 前端最讓我苦惱的就是: (1)定制樣式必須要依賴于插件內(nèi)部生成的html代碼. (2)繁瑣的樣式文件和配置, 還需要手動設(shè)置.
在使用這款插件時, 本來想要借助作者提供的樣式文件的, 結(jié)果一看有四五個, 而且無還不知道怎么配置(沒有文檔說明), 再加上還要依賴于jquery... 瞬間就失去了興趣了. 我的要求是, 插件嘛, 一個js, 一個css搞定. 這才叫清爽.
- 個人覺得
bootstrap的分頁條比較簡潔好看, 但是這款插件不支持.
優(yōu)化
(1)不想學(xué)習(xí)配置樣式; (2)喜歡bootstrap分頁條.
于是, 想起來, 研究下源碼吧, 看看能不能優(yōu)化下, 實現(xiàn)我的需求.
插件有個參數(shù)mode: (1)fixed 分頁按鈕固定, (2)unfixed, 分頁按鈕不固定.
源碼長這樣:

既然這樣, 我就想, 不如給你加個mode, 就叫做: bootstrap. 當(dāng)我如下配置時, 會給出來bootstrap樣式的分頁條.


優(yōu)化代碼片
增加一個case分支.
case 'bootstrap': // +:引入bootstrap的分頁導(dǎo)航條 Nisus 2018-1-31 15:21:51 bug: 目前設(shè)置首頁和末頁后, 下一頁有bug, 當(dāng)前頁為1時, 下一頁不往下走.
//bootstrap分頁的起始
html += '<nav aria-label="Page navigation"><ul class="pagination">';
if (opts.coping) {
var home = opts.coping && opts.homePage ? opts.homePage : '1';
//首頁
// html += '<a href="javascript:;" data-page="1">' + home + '</a>';
var startCls = '';
if (current == 1) {
startCls = 'active';
}
html += '<li class="' + startCls + '"><a href="javascript:;" data-page="1">' + home + '</a></li>';
}
//上一頁
// html += '<li>\n' +
// ' <a class="' + opts.prevCls + '" href="javascript:;" aria-label="Previous">' + opts.prevContent +
// ' </a>' +
// ' </li>';
html += '<li><a href="javascript:;" class="' + opts.prevCls + '" aria-label="Previous">' + opts.prevContent + '</a></li>';
// <span aria-hidden="true">' + opts.prevContent + '</span>
var start = current > opts.count - 1 ? current + opts.count - 1 > pageCount ? current - (opts.count - (pageCount - current)) : current - 2 : 1;
var end = current + opts.count - 1 > pageCount ? pageCount : start + opts.count;
for (; start <= end; start++) {
if (start != current) {
html += '<li><a href="javascript:;" data-page="' + start + '">' + start + '</a></li>';
} else {
html += '<li class="active"><a href="javascript:;" data-page="' + start + '">' + start + '</a></li>';
}
}
//下一頁
html += '<li><a href="javascript:;" class="' + opts.nextCls + '" aria-label="Next">' + opts.nextContent + '</a></li>';
// html += '<li>' +
// ' <a class="' + opts.nextCls + '" href="javascript:;" aria-label="Next">' +
// ' <span aria-hidden="true">' + opts.nextContent + '</span>' +
// ' </a>' +
// ' </li>';
if (opts.coping) {
var _end = opts.coping && opts.endPage ? opts.endPage : pageCount;
//末頁
var endCls = '';
if(current===pageCount) {
endCls = 'active';
}
html += '<li class="' + endCls + '"><a href="javascript:;" data-page="' + pageCount + '">' + _end + '</a></li>';
// html += '<a href="javascript:;" data-page="' + pageCount + '">' + _end + '</a>';
}
// //尾部
html += '</ul></nav>';
break;
應(yīng)用
頁面使用list.jsp, 后臺分頁使用mybatis的PageHelper插件實現(xiàn)分頁查詢數(shù)據(jù).
流程:
- 第一次請求
list.jsp頁面時, 分頁數(shù)據(jù)采用默認值, 后臺參數(shù)封裝類叫做BrandQuery, 該pojo設(shè)置分頁默認值(當(dāng)前頁1, 頁大小9). 服務(wù)器響應(yīng)頁面后, 頁面數(shù)據(jù)位加載數(shù)據(jù), 分頁條處加載分頁條. 關(guān)鍵點: 后臺需要回傳當(dāng)前頁, 讓分頁插件接收到, 這樣才能讓當(dāng)前分頁按鈕高亮. - 之后, 點擊分頁按鈕后, 進入插件中配置的
callback(回調(diào)函數(shù)), 發(fā)送表單請求. 請求list.jsp. 實現(xiàn)更新數(shù)據(jù).
前端
引入插件
下載插件包. 然后在jsp頁面中引入.
- jquery.js
- jquery.pagination.js
- bootstrap的css
<!--使用jquery.pagination.js插件的bootstrap分頁條樣式需要引用的js,css文件-->
<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="/js/plugins/jquery.pagination.js"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!--///使用jquery.pagination.js插件的bootstrap分頁條樣式需要引用的js,css文件-->
數(shù)據(jù)位接受后臺數(shù)據(jù)
響應(yīng)的數(shù)據(jù), 圖省事, 也封裝在了BrandQuery類中.

分頁位置代碼
<!-- START: 分頁導(dǎo)航條 -->
<div class="page-nav"></div>
<script type="text/javascript">
//記錄當(dāng)前頁
var current = ${brandQuery.current};
current = current === null?1:current;
$('.page-nav').pagination({
mode:'bootstrap', //生成bootstrap風(fēng)格的分頁條
/* ABANDON: 會有bug, 導(dǎo)致'下一頁'在當(dāng)前頁為1時失效
coping: true,
homePage: '首頁',
endPage: '末頁',
*/
prevContent: '上頁',
nextContent: '下頁',
jump:true,
current:current,
callback:function (api) {
$('#ipt_current').val(api.getCurrent());
$('#queryFormId').submit();
}
})
</script>
<!-- END: 分頁導(dǎo)航條 -->
后臺
controller
/**
* 跳轉(zhuǎn)至 ./brand/*
*/
@RequestMapping(value = {"/brand/{page}"})
public String gotoBrandtPage(@PathVariable String page, BrandQuery brandQuery, Model model){
page = "brand/"+page; //不能加 / 了, xml中配置的前綴已經(jīng)含有 /
log.debug("跳轉(zhuǎn)至:{}", page);
// 查詢數(shù)據(jù)
// 給默認值
// 默認顯示出 is_display = 1 i.e. 可見的
if (brandQuery.getIs_display() == null) {
brandQuery.setIs_display(1);
}
// List<Brand> brands = brandService.queryBrandByNoPage(brandQuery);
brandQuery = brandService.queryBrandByPage(brandQuery);
model.addAttribute("brandQuery", brandQuery);
//查詢條件的回顯
model.addAttribute("name", brandQuery.getName());
model.addAttribute("is_display", brandQuery.getIs_display());
return page;
}
service
public BrandQuery queryBrandByPage(BrandQuery brandQuery) {
//開啟分頁查詢
PageHelper.startPage(brandQuery.getCurrent(), brandQuery.getShowData());
//仍然借用正常非分頁查詢的mapper方法
List<Brand> brands = brandMapper.queryBrandByNoPage(brandQuery);
/*!為了最大限度讓用戶以前的查詢代碼絲毫不用變, 改查list就查list!
* 想獲取分頁信息, 使用包裝類即可. 若不嫌麻煩, 也可以修改mapper.xml, 讓其返回Page<>對象*/
//獲取分頁信息
// PageInfo<Brand> pageInfo = new PageInfo<>(brands);
// int pageCount = pageInfo.getPageNum();
Page page = (Page) brands;
brandQuery.setPage(page);
brandQuery.setCurrent(page.getPageNum());
return brandQuery;
}
效果

不足
- 存在bug, 增加
首頁和末頁按鈕后,下一頁的按鈕在當(dāng)前頁為1時失效. - 分頁條樣式有缺陷, 比如效果圖中的,
跳轉(zhuǎn)非常難看.
附
PageHelper依賴
我覺的只是個設(shè)計精妙的插件. 你可以在原有的dao層代碼絲毫不動的情況下, 實現(xiàn)分頁功能. 即你不需要為了分頁, 而修改mapper接口和mapper.xml. 只需要在查詢前, 加上 PageHelper.startPage(...).
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.1</version>
</dependency>