最近工作不是很忙,所以就看看淘宝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>