使用jQuery实现自定义的分页导航插件,效果如下图:
MyWeb UI Examples
$.fn.ryanPagination = function(settings){
var opts = $.extend({}, {
showPageNum: 9,
pageSize: 10, // 默认每页展示10条记录
showTitle: false // 是否展示导航按钮的title信息
}, settings);
// 计算数据总页数
opts.totalPage = Math.ceil(settings.totalSize / opts.pageSize);
var beginPage = opts.totalPage > 0 ? 1 : 0,
navObj = this;
$(navObj).empty().append(
$("").addClass("page-nav-left").attr("id", "page-nav-left")
).append(
$("").addClass("page-nav-right").attr("id", "page-nav-right")
);
var initPageRecord = function(beginPage, totalPage, showPageNum, totalSize){
$("div#page-nav-left").append(
$("").html("当前记录: 第 ")
).append(
$("").attr("id", "from-size").html("0")
).append(
$("").html(" - ")
).append(
$("").attr("id", "to-size").html("0")
).append(
$("").html(" 条 / 共 ")
).append(
$("").attr("id", "total-size").html(totalSize)
).append(
$("").html(" 条, 第 ")
).append(
$("").attr("id", "cur-page").html("0")
).append(
$("").html(" 页 / 共 ")
).append(
$("").attr("id", "total-page").html(totalPage)
).append(
$("").html(" 页 ")
);
};
var initPageNav = function(beginPage, totalPage, showPageNum, totalSize){
// 清空原有页标,重新设置
$("div#page-nav-right").empty().append(
$("").html("首页").attr({"type": "text", "index": "first", "title": "首页"})
).append(
$("").html("<<").attr({"type": "text", "index": "previous", "title": "上一页"})
).append(
function(){
var _strHml_ = "";
var _span_ = function(idx){
return ""+_subStr_(idx)+"";
};
// 避免分页下标过大导致排版异常
var _subStr_ = function(str){
str += "";
if(str.length > 3){
str = str.substring(0, 3) + "..";
}
return str;
}
// 请求数据集为空
if(beginPage === 0){
return _span_(beginPage);
}
// 返回数据集的页数在展示的范围内
if(totalPage <= showPageNum){
for (var i = 1; i <= totalPage; i++) {
_strHml_ = _strHml_ + _span_(i);
}
return _strHml_;
}
// 返回数据集的页数超出展示的范围,展示一半的页数
var temp = totalPage + 1 - showPageNum; // 临界值
var _half_ = Math.floor((showPageNum - 1) / 2);
var _p_ = beginPage >= temp ? temp : beginPage, // 前一段的起始页标
_k_ = totalPage - _half_ + 1; // 后一段的起始页标
if((totalPage - beginPage + 1) <= showPageNum){
for (var i = _p_; i <= totalPage; i++) {
_strHml_ = _strHml_ + _span_(i);
}
}else{
if(beginPage >= _half_){
for (var i = beginPage; i < beginPage + _half_; i++) {
_strHml_ = _strHml_ + _span_(i);
}
}else{
for (var i = 1; i <= _half_; i++) {
_strHml_ = _strHml_ + _span_(i);
}
}
// 无法显示的分页下标省略处理
_strHml_ = _strHml_ + "···";
for (var i = totalPage - _half_ + 1; i <= totalPage; i++) {
_strHml_ = _strHml_ + _span_(i);
}
}
return _strHml_;
}
).append(
$("").html(">>").attr({"type": "text", "index": "next", "title": "下一页"})
).append(
$("").html("末页").attr({"type": "text", "index": "last", "title": "末页"})
);
// 数据集为空,不在对相关事件进行处理
if(beginPage === 0){ return; }
if(opts.showTitle == false){ // 移除导航按钮title属性
$("span[index]", $("div#page-nav-right")).removeAttr("title");
}
var __navBtnClick__ = function(){
var type = $(this).attr("type"),
curPage = $(this).attr("index");
if(type === 'number' && curPage > 0){
$("span#cur-page").html(curPage);
$("span#from-size").html((parseInt(curPage)-1)*opts.pageSize+1);
$(this).addClass("active").siblings("span").removeClass("active");
if($("span.active").attr("index")*1 == totalPage){
$("span#to-size").html(totalSize);
}else{
var toSize = parseInt(curPage)*opts.pageSize;
$("span#to-size").html(toSize > totalSize ? totalSize : toSize);
}
}else if(type === 'text'){
var _tidx_ = 0;
if(curPage === 'previous'){
_tidx_ = $("span.active").attr("index")*1 - 1;
}else if (curPage === 'next'){
_tidx_ = $("span.active").attr("index")*1 + 1;
}else if (curPage === 'first'){
_tidx_ = 1;
}else if (curPage === 'last'){
_tidx_ = totalPage;
}
initPageNav(_tidx_, totalPage, showPageNum, totalSize);
}
};
var __navBtnController__ = function(index, allowed, disabled){
var spanObj = $("span[index='"+index+"']", $("div#page-nav-right"))
.css("cursor", allowed ? "pointer" : "not-allowed")
.prop("disabled", disabled);
if(disabled == true){
spanObj.unbind("click");
}else{
spanObj.unbind("click").bind("click", __navBtnClick__);
}
};
// 分页区按钮点击事件
$("div#page-nav-right > span").unbind("click").bind("click", __navBtnClick__);
$("div#page-nav-right > span[type='text']").bind({
"mouseover": function(){
var curPage = $("span.active", $("div#page-nav-right")).attr("index")*1;
if(curPage === 1){
__navBtnController__("first", false, true);
__navBtnController__("previous", false, true);
}else if(curPage === opts.totalPage){
__navBtnController__("last", false, true);
__navBtnController__("next", false, true);
}
},
"mouseout": function(){
__navBtnController__("first", true, false);
__navBtnController__("previous", true, false);
__navBtnController__("last", true, false);
__navBtnController__("next", true, false);
}
});
$("span[index='"+beginPage+"']", $("div#page-nav-right")).click();
};
// 设置当前页数据记录
initPageRecord(beginPage, opts.totalPage, opts.showPageNum, opts.totalSize);
// 设置导航页的展示
initPageNav(beginPage, opts.totalPage, opts.showPageNum, opts.totalSize);
};
@charset "utf-8"
.page-nav {
height: 45px;
background-color: #efefef;
border: 1px solid #ccc;
margin-top: 100px;
}
.page-nav > div {
height: inherit;
line-height: 2em;
padding-top: 5px;
}
.page-nav > div > span {
font-size: 13px;
}
.page-nav .page-nav-left {
float: left;
padding-left: 20px;
}
.page-nav .page-nav-right {
float: right;
padding-right: 20px;
}
.page-nav .page-nav-right span {
height: 28px;
width: 34px;
border: 1px solid #ccc;
text-align: center;
border-left-width: 0;
padding: 2px 4px;
cursor: pointer;
display: inline-block;
}
.page-nav .page-nav-right span:first-child {
border-left-width: 1px;
}
.active {
background-color: #1E90FF;
color: #FFFFFF;
}