最近工作不是很忙,所以就看看淘寶kissy分頁元件原始碼,感覺程式碼也不怎麼難 容易理解,所以就按照他們的思路自己重新理一遍,來加深自己對他們的理解,同時對他們的分頁元件進行一些重構(因為他們分頁是做好了,但是不能直接拿來用,所以就封裝了下),所以就用jquery封裝了一個。
配置引數如下:
影響分頁元件資訊展現的因素如下圖所示:
元件提供以下配置引數: totalPage
,總頁數,預設值為1 , currentPage
,初始選中的頁碼,預設值為1 ,firstPagesCount
,最前面的展現頁數,預設值為2, preposePagesCount
,當前頁的緊鄰前置頁數,預設值為2 ,postposePagesCount
,當前頁的緊鄰後置頁數,預設值為1, lastPagesCount
,最後面的展現頁數,預設值為0 , render
,是否自動渲染元件,預設值為true。
對外公開的方法:
render(): 渲染元件
show(): 顯示元件
hide(): 隱藏元件
destory(): 銷燬元件
頁碼顯示及對應的HTML結構渲染問題:
一: 當前“選中的頁”前面HTML結構渲染的方式如下:
判斷當前選中的頁碼 如果小於或者等於 (最前面的展示頁數 + 當前頁的緊鄰前置頁數 +1)的話
if (currentPage <= firstPagesCount + preposePagesCount + 1) {
for(var i=1; i<currentPage; i++) {
pageHTML += self._renderActivePage(i);
}
}
這種情況下:對應的描述圖如下:
對應的HTML結構程式碼如:
那麼否則的話 // 對應圖3
else {
for(var i=1; i<= firstPagesCount; i++) {
pageHTML += self._renderActivePage(i);
}
pageHTML += '<span class="pagination-break">...</span>';
for(var i = currentPage-preposePagesCount; i <= currentPage-1; i++) {
pageHTML += self._renderActivePage(i);
}
}
那麼對應的描述圖如這樣的:
圖3:
渲染HTML結構:
接著 就是當前選中的頁 html結構
// 當前頁的頁碼 html顯示
pageHTML += '<span class="pagination-curr">' + currentPage + '</span>';
二: 當前頁頁碼後面的html展示
如果當前頁 大於或者等於 (總頁數 - 最後面的展現頁數 - 當前頁的緊鄰後置頁數)的話 程式碼如下:
if (currentPage >= totalPage - lastPagesCount - postposePagesCount) {
offset = currentPage + 1;
for(var i=currentPage+1; i<=totalPage; i++) {
pageHTML += self._renderActivePage(i);
}
}
對應的圖如下:
對應的HTML結構渲染如下:
否則的話:程式碼如下
else {
for(var i=currentPage+1; i<= currentPage+postposePagesCount; i++) {
pageHTML += self._renderActivePage(i);
}
pageHTML += '<span class="pagination-break">...</span>';
for(var i=totalPage-lastPagesCount+1; i<=totalPage; i++) {
pageHTML += self._renderActivePage(i);
}
}
對應圖如下:
對應的HTML結構渲染如下:
最後判斷下一頁的顯示方式 程式碼如下:
pageHTML += currentPage === totalPage ? '<span class="pagination-end"><span>下一頁</span></span>' : '<a class="pagination-next"><span>下一頁<span></a>';
Jquery所有的JS程式碼如下:
/**
* fileoverview Jquery分頁元件
* @param {selector} 分頁容器
* @param {cfg} object 預設配置
*/
var Pagination = (function(){
function Pagination(selector,cfg){
if(this instanceof Pagination) {
// 匹配傳引數clickElem
if($.isPlainObject(selector)){
this.selector = selector;
}else if(/^\./.test(selector)){
this.selector = $(selector);
}else if(/^#/.test(selector)){
this.selector = $(selector);
}else if($('.'+selector)){
this.selector = $('.'+selector);
}else {
throw new Error('傳遞引數不符合!');
}
}else {
new Pagination(selector,cfg);
}
cfg = $.extend(Pagination.config,cfg || {});
this.config = cfg || {};
// 初始化時候 預設選中的頁數
$.isFunction(this.config.callback) && this.config.callback(this.config.currentPage);
this._init();
}
Pagination.config = {
// 總頁數
totalPage:1,
// 預設選中的頁數
currentPage: 1,
//當前頁最大緊鄰前置頁數(不包括最前面顯示頁數)
preposePagesCount: 2,
//當前頁的最大緊鄰後置頁數
postposePagesCount: 1,
// 第一個"..."前顯示的頁數
firstPagesCount: 2,
// 第二個"..."後顯示的頁數
lastPagesCount: 0,
render: true,
callback: function(idx){}
};
Pagination.prototype = {
_init: function(){
var self = this;
if(self.config.render === true){
self.render();
}
},
/* 渲染 */
render: function(){
var self = this;
self._renderUI();
self._bindUI();
},
_renderUI: function(){
var self = this;
self._resetPagination();
},
// 處理點選元素
_bindUI: function(){
var self = this;
/*
* 注意jquery1.9 沒有live這個方法 所以在jquery1.9 API上會報錯 jquery1.9以上考慮用其他的繫結事件方法
*/
$('.pagination-spec').live('click',function(e){
var target = e.target,
toPage = $(target).attr('data-page') * 1;
self._switchToPage(toPage);
});
$('.pagination-prev').live('click',function(e){
var toPage = self.config.currentPage - 1;
self._switchToPage(toPage);
});
$('.pagination-next').live('click',function(e){
var toPage = self.config.currentPage + 1;
self._switchToPage(toPage);
});
},
_switchToPage: function(page){
var self = this;
self.config.currentPage = page;
self._resetPagination();
// 頁面顯示成功後 回撥
$.isFunction(self.config.callback) && self.config.callback(self.config.currentPage);
},
/*
* 重新整理分頁
*/
_resetPagination: function(){
var self = this,
pageHTML = '',
totalPage = self.config.totalPage > 0 ? self.config.totalPage : 1,
currentPage = (self.config.currentPage <= totalPage) && (self.config.currentPage > 0) ? self.config.currentPage : 1,
preposePagesCount = self.config.preposePagesCount >=0 ? self.config.preposePagesCount : 2,
postposePagesCount = self.config.postposePagesCount >=0 ? self.config.postposePagesCount : 1,
firstPagesCount = self.config.firstPagesCount >=0 ? self.config.firstPagesCount : 2,
lastPagesCount = self.config.lastPagesCount >=0 ? self.config.lastPagesCount : 0,
offset;
// 當前頁碼顯示
pageHTML += currentPage === 1 ? '<span class="pagination-start"><span>上一頁</span></span>' :
'<a class="pagination-prev"><span>上一頁</span></a>';
//當前頁的 前面html結構顯示問題
if (currentPage <= firstPagesCount + preposePagesCount + 1) {
for(var i=1; i<currentPage; i++) {
pageHTML += self._renderActivePage(i);
}
}else {
for(var i=1; i<= firstPagesCount; i++) {
pageHTML += self._renderActivePage(i);
}
pageHTML += '<span class="pagination-break">...</span>';
for(var i=currentPage-preposePagesCount; i<=currentPage-1; i++) {
pageHTML += self._renderActivePage(i);
}
}
// 當前頁的頁碼 html顯示
pageHTML += '<span class="pagination-curr">' + currentPage + '</span>';
// 當前頁頁碼後面的html展示
if (currentPage >= totalPage - lastPagesCount - postposePagesCount) {
offset = currentPage + 1;
for(var i=currentPage+1; i<=totalPage; i++) {
pageHTML += self._renderActivePage(i);
}
} else {
for(var i=currentPage+1; i<= currentPage+postposePagesCount; i++) {
pageHTML += self._renderActivePage(i);
}
pageHTML += '<span class="pagination-break">...</span>';
for(var i=totalPage-lastPagesCount+1; i<=totalPage; i++) {
pageHTML += self._renderActivePage(i);
}
}
pageHTML += currentPage === totalPage ? '<span class="pagination-end"><span>下一頁</span></span>' :
'<a class="pagination-next"><span>下一頁<span></a>';
$(self.selector).html(pageHTML);
},
/**
* @ 渲染可點選的頁碼
* @param index {Number} 頁碼索引
*
*/
_renderActivePage: function(index) {
return '<a class="pagination-spec" data-page="' + index + '">' + index + '</a>';
},
show: function(){
var self = this;
$(self.selector).show();
},
hide: function(){
var self = this;
$(self.selector).hide();
},
// 銷燬
destory: function(){
var self = this;
$(self.selector) = null;
// 銷燬用live繫結的事情
$('.pagination-spec').die('click');
$('.pagination-prev').die('click');
$('.pagination-next').die('click');
}
};
return Pagination;
})();
HTML呼叫方式如下:
<div id = "Pagination"></div>
<div id="content"></div>
<script type="text/javascript">
var intPageSize = 8, //一頁定義8條資料
intRowCount = 100; //記錄總數
intPageCount = Math.ceil(intRowCount/intPageSize);
new Pagination('#Pagination',{
totalPage: intPageCount,
callback: function(idx){
console.log(idx);
}
});
</script>
其中一頁顯示多少條intPageSize 是使用者自定義的,
記錄總數intRowCount 是後臺開發人員給的,
總共多少頁 intPageCount 是我們要計算的。
初始化方式如上 通過例項化。
然後callback回撥函式 把相對應的 每頁顯示多少條intPageSize
和 相對應的頁碼 idx ajax方式傳參提交給開發人員
返回相應的資訊 我們渲染出來 就ok!
css也放上來吧!如下
<style>
body {
font: 12px/1.5 tahoma,arial,宋體b8b\4f53;
}
.pagination-start,
.pagination-prev,
.pagination-next,
.pagination-end
{
width: 36px;
background: url(http://img04.taobaocdn.com/tps/i4/T1cP85XihuXXXXXXXX-13-101.png) no-repeat;
}
.pagination-start,
.pagination-prev,
.pagination-next,
.pagination-end,
.pagination-spec,
.pagination-curr,
.pagination-break
{
min-width: 16px;
_width: 16px;
border: 1px solid #ccc;
display: inline;
float: left;
height: 24px;
margin-right: 3px;
padding: 0 5px;
line-height: 24px;
text-align: center;
font-family: Tahoma,SimSun,Arial;
vertical-align: top;
white-space: nowrap;
overflow: hidden;
}
.pagination-start {
padding-left: 16px;
background-position: 5px 8px;
}
.pagination-prev {
padding-left: 16px;
background-position: 0 -12px;
}
.pagination-curr {
font-weight: 700;
color: #fd6d01;
background-color: #ffede1;
border: 1px solid #fd6d01;
}
.pagination-break {
color: #c0c0c0;
border: 0;
}
.pagination-next {
padding-right: 16px;
background-position: 42px -50px;
}
.pagination-end {
padding-right: 16px;
background-position: 47px -31px;
}
a {
color: #36c;
cursor: pointer;
}
a:hover {
border: 1px solid #fd6d01;
}
</style>