一个 javascript 页码控件 ,支持ajax 翻页,CSS 比较难看,设置成禁用默认样式, 可以根据CSS类名另外写样式
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=content-type content="text/html; charset=utf-8">
<script>
var PageNav = (function(){
var _id = 1; //用于标记不同的页码控件
function f(options,extParam,callback){
this.options={ //默认参数
container:null,//父容器,id或Dom对象
pagecount:1,//总页数
defaultPage:null, //控件初始化之后默认显示的页码,用于覆盖url页码参数,特殊情况下使用
sibNum:4, //当前页左右相邻页码数量
pageKey:'page', //页码在url上使用的参数名
reload:true,//是否在点击页码时重载页面,如果是ajax翻页,设为false
nextPrev:true, //是否显示上一页下一页按钮
firstLast:false,//是否显示首页尾页按钮
anyPage:true, //是否显示页码输入框和跳转按钮
dotted:true, //是否在不连惯页码的位置插入省略号
defaultStyle:true //是否使用默认控件样式,wait...
};
this.curPage = 1; //当前页码
this.gotoPage = 1; //将要跳转到的页码
this.lockedParams={}; //锁定不允许修改的url参数,如: {key1:true,key2:true}
this.extParam={}; //在url上额外显示的参数,{key1:1,key2:function(param,true){}},在函数内使用this可以访问页码控件, 如果值为函数自动设置第一个参数为当前页码,如果给出第二个参数(任意值),设第一个参数为页码控件对象,其他参数不再受理
this.callbacks=[]; //页码跳转前执行的回调函数,可以多个
this.id = 'pageBar_'+(_id++); //页码控件id
this.pageBarDom = null; //页码控件初始化之后保存在这里,如果初始化时未指定container,可以通过该属性找到控件
this.barStyle={ //默认样式,渣 css,不能自理,自重...,页码按钮使用span而不是 a 标签,因此低版本IE没有hover样式效果
'pageBar-hoder':"position:relative;display:none;margin:3px;border:0px;font-family:'arial,sans-serif';font-size:12px;text-align:center;height:25px;line-height:25px;zoom:1;",
'pageBar-all-btn':"position:relative;display:inline-block;margin:0px 1px;border:1px solid #ccc; border-radius:3px;color:#0066cc;height:25px;line-height:25px;cursor:pointer;zoom:1;vertical-align:middle;",
'pageBar-all-btn-hover':"",
'pageBar-page-btn':"width:30px;",
'pageBar-page-btn-hover':"background-color:#AC75BA;",
'pageBar-curPage-btn':"border:0px;color:red;background-color:white;",
'pageBar-curPage-btn-hover':"background-color:white;",
'pageBar-nextPrev-btn':"width:45px;",
'pageBar-nextPrev-btn-hover':"background-color:#23fdac;",
'pageBar-firstLast-btn':"width:45px;",
'pageBar-firstLast-btn-hover':"background-color:#da4587;",
'pageBar-anyPage-btn':"width:30px;",
'pageBar-anyPage-btn-hover':"background-color:#ad45ff;",
'pageBar-anyPage-input':"width:35px;height:25px;line-height:25px;margin:0px 1px;border:1px solid #ccc; border-radius:3px;vertical-align:middle;" ,
'pageBar-hoder-hover':'background-color:white'
};
var args=[];
for(var i=0,len=arguments.length; i<len;i++)
{
args.push(arguments[i]);
}
this.init.apply(this,args);
}
f.prototype={
constructor:f,
init:function(options,extParam,callback){ //接受用户传入参数并初始化控件
var host = this;
for(var i=0;i<arguments.length;i++)
{//接收参数
if(arguments[i]===undefined){
continue;
}else if(typeof(arguments[i])==='string'||!arguments[i]||arguments[i].nodeType==1&&arguments[i].ownerDocument.nodeType==9){//字符串、false、null、DOM节点参数作为容器ID接收,如果有多个,只接收最右边的一个
host.options.container = arguments[i]||null;
}else if(typeof(arguments[i])==='number'){//数字参数作为总页数接收
arguments[i]>0?host.options.pagecount=arguments[i]:'';
}else if(arguments[i].constructor===Function){ //函数参数全部作为回调函数接收,苹果浏览器把正则表达式判断为function型
host.callbacks.push(arguments[i]);
}else if(Object.prototype.toString.call(arguments[i])==='[object Object]'){ //object字面量参数作为options或extParam处理,其他古怪型参数不受理
if(!i){ //options设置只能放在第一个参数,否则全部作为额外附加URL参数清单接收
host._paramsJoin(host.options,arguments[i]);
}else{
host._paramsJoin(host.extParam,arguments[i]);
}
}
}//end for
//修正container为dom对象
var container = host.options.container;
container&&typeof(container)==='string'&&(host.options.container=host._getById(container));
//如果已经创建过控件,再次调用init方法将使用新参数重建控件
host.get()&&(host.get().innerHTML = "");
host.lockParams(host.options.pageKey) //锁定页码参数关键字
.setCurPage() //指定当前页码
.create() //创建页码控件
.createStyle()
.show(); //显示页码
return host;
},
get:function(){ //获取控件Dom对象
var host = this;
return host._getById(host.id)||host.pageBarDom;
},
show:function(container){//显示控件
var host = this;
//修正父容器
var container = arguments[0]||host.options.container;
if(typeof(container)=='string'){
container = host._getById(arguments[0]);
}
host.options.container = container;
var pageBar = host.get();
pageBar.style?pageBar.style.display="inline-block":pageBar.style.cssText="display:inline-block";
if(host.options.pagecount >1){
container&&container.appendChild(pageBar);
}
return host;
},
hide:function(){//隐藏控件
var host = this;
var pageBar = host.get();
pageBar.style?pageBar.style.display="none":pageBar.style.cssText="display:none";
return host;
},
destroy:function(){//销毁控件
var host = this;
var pageBar = host.get();
pageBar.parentNode.removeChild(pageBar);
return null;
},
excePage:function(page){ //执行页码翻页动作
var host = this;
if(!arguments.length||host.curPage==arguments[0]){
return host;
}
host._setGotoPage(page);
var gotoPage = host.getGotoPage();
for(var i=0,len=host.callbacks.length;i<len;i++)
{//执行翻页前的回调函数
host.callbacks[i].call(host,host.callbacks[i].length>1?host:gotoPage);
}
if(!host.options.reload){
host.setCurPage(gotoPage);
host.reFleshBar();
}else{//跳转
window.location.href=host._getNewUrl();
}
return host;
},
lockParams:function(params,frag){//加锁、解锁参数
var host = this;
if(typeof(params)==='string'){//单个参数
arguments[1]?host.lockedParams[params]=true:(function(){delete host.lockedParams[params];})();
}else if(Object.prototype.toString.call(params)=='[object Array]'){ //数组形式的多个参数
for(var i=0,len=params.length;i<len;i++)
{
arguments[1]?host.lockedParams[params[i]]=true:(function(){delete host.lockedParams[params[i]];})();
}
}else if(Object.prototype.toString.call(params)=='[object Object]'){ //{key:frag}
for(var key in params){
params[key]?host.lockedParams[key]=true:(function(){delete host.lockedParams[key];})();
}
}
return host;
},
setAnchor:function(key,val){ //设置锚点
var host = this;
var anchor=[arguments[0],arguments[1]].join('=').replace(/(^\=)|(\=$)/,'');
if(anchor){
window.location = window.location.toString().split("#")[0]+"#"+anchor;
}
return host;
},
getAnchor:function(){
return window.location.hash.substr(1);
},
setCurPage:function(curPage){ //设置当前页码
var host = this;
var page = arguments[0]
||host.options.defaultPage
||window.location.search.split(host.options.pageKey+'=')[1];
host.curPage = [1,parseInt(page)||1,host.options.pagecount].sort(function(a,b){ return a-b;})[1];
return host;
},
getCurPage:function(){//获取当前页码
var host = this;
return host.curPage;
},
_setGotoPage:function(page){ //设置将要跳转的页码
var host = this;
host.gotoPage = [1,parseInt(arguments[0])||1,host.options.pagecount].sort(function(a,b){ return a-b;})[1];
return host;
},
getGotoPage:function(){
var host = this;
return host.gotoPage;
},
_getById:function(id){ //按id获取DOM元素
return document.getElementById(arguments[0]);
},
_getUrlParams:function(){ //获取url参数
var host = this;
var urlParams = {};
var urlParamsArr = window.location.search.substr(1).replace(/(^\&)|(\&$)/,'');
urlParamsArr = urlParamsArr?urlParamsArr.split("&"):[];
for(var i=0,len=urlParamsArr.length;i<len;i++)
{
var paramArr = urlParamsArr[i].split("=");
urlParams[paramArr[0]]=paramArr[1]==undefined?undefined:paramArr[1].replace(/(^\s)|($\s)/,'');
}
return urlParams;
},
_paramsJoin:function(paramsExist,addParams,lockedParams){ //合并对象键值
//addParams 要合并的参数,paramsExist 原url存在的参数,lockedParams锁定的参数不允许替换
var host = this;
//不受理非键值型对象
if(Object.prototype.toString.call(addParams)!='[object Object]'){ return paramsExist; }
var newParams=paramsExist;
var lockedParams = lockedParams||host.lockedParams;
//新增参数,如有和原参数重复,覆盖原参数,锁定的参数除外
for(var key in addParams){
//不接受addParams对象继承来的属性
if(!addParams.hasOwnProperty(key)||lockedParams[key]){continue;}
if((addParams[key]).constructor===Function){
newParams[key] = addParams[key](addParams[key].length>1?host:host.getGotoPage());
}else if(typeof(addParams[key])!='number'
&& typeof(addParams[key])!='string'
&& typeof(addParams[key])!='boolean'){
newParams[key] = '';
}else{
newParams[key]=addParams[key];
}
}
return newParams;
},
_getNewUrl:function(){ //生成新网址
var host = this;
var urlParams = host._paramsJoin(host._getUrlParams(),host.extParam);
urlParams[host.options.pageKey] = host.getGotoPage(); //新页码
var url = window.location;
var mainUrl = [url.protocol,'//',url.host,url.pathname].join(''); //网址
var antor = url.hash; //锚点
var searchArr = []; //参数
for(var key in urlParams)
{
searchArr.push(urlParams[key]==undefined?key:[key,urlParams[key]].join('='));
}
var searchStr = searchArr.join('&');
searchStr = searchStr?'?'+searchStr:'';
var newUrl = [mainUrl,searchStr,antor].join('');
return newUrl;
},
reFleshBar:function(){ //刷新页码控件,用于无刷新翻页
var host = this;
var pageBar = host.get();
pageBar.innerHTML="";
host.create().show();
return host;
},
create:function(){ //组装pagebar
var host = this;
var curPage = host.curPage;
var maxPage = host.options.pagecount;
var sibNum = host.options.sibNum;
var start = Math.max(1,[1,curPage-sibNum,maxPage-2*sibNum].sort(function(a,b){return a-b;})[1]);
var end = Math.min(start+sibNum*2,maxPage);
var pageBar=host.pageBarDom||host._createBarElm(0);
var pageBtn=host._createBarElm(1);
var firstLastBtn = host._createBarElm(2);
var nextPrevBtn = host._createBarElm(3);
var gotoBtn = host._createBarElm(4);
var input = host._createBarElm(5);
var newPageBtn;
if(curPage>1&&host.options.firstLast){
var firstBtn = firstLastBtn.cloneNode(true);
firstBtn.appendChild(host._createBarElm(6,'首页'));
firstBtn.onclick = function(){
host.excePage(1);
}
pageBar.appendChild(firstBtn);
if(start==1){ start++;}
}else if(start>1){
newPageBtn = pageBtn.cloneNode(true);
newPageBtn.onclick = function(){
host.excePage(parseInt(this.innerHTML));
};
pageBar.appendChild(newPageBtn).appendChild(host._createBarElm(6,1));
}
if(start>2&&host.options.dotted)
{
pageBar.appendChild(host._createBarElm(6,'...'));
}
do{
newPageBtn = pageBtn.cloneNode(true);
newPageBtn.onclick = function(){
host.excePage(parseInt(this.innerHTML));
};
if(start==curPage){
newPageBtn.className="pageBar-page-btn pageBar-curPage-btn";
}
pageBar.appendChild(newPageBtn).appendChild(host._createBarElm(6,start));
start++;
}while(start<=end);
if(end<maxPage-1&&host.options.dotted){
pageBar.appendChild(host._createBarElm(6,'...'));
}
if(curPage<maxPage&&host.options.firstLast){
var lastBtn = firstLastBtn.cloneNode(true);
lastBtn.appendChild(host._createBarElm(6,'尾页'))
lastBtn.onclick = function(){
host.excePage(maxPage);
}
pageBar.appendChild(lastBtn);
if(end==maxPage){ end--;}
}else if(end<maxPage){
newPageBtn = pageBtn.cloneNode(true);
newPageBtn.onclick = function(){
host.excePage(parseInt(this.innerHTML));
};
pageBar.appendChild(newPageBtn).appendChild(host._createBarElm(6,maxPage));
}
if(host.options.nextPrev){ //上一页下一页按钮
if(curPage>1){
var prevBtn = nextPrevBtn.cloneNode(true);
prevBtn.onclick=function(){
host.excePage(curPage-1);
}
prevBtn.appendChild(host._createBarElm(6,'上一页'));
pageBar.insertBefore(prevBtn,pageBar.firstChild);
}
if(curPage<maxPage){
var nextBtn = nextPrevBtn.cloneNode(true);
nextBtn.onclick=function(){
host.excePage(curPage+1);
}
nextBtn.appendChild(host._createBarElm(6,'下一页'));
pageBar.appendChild(nextBtn);
}
}
if(host.options.anyPage){ //页码跳转输入框及按钮
var newGotoBtn = gotoBtn.cloneNode(true);
var newInput = input.cloneNode(true);
newGotoBtn.onclick=function(){
var npage = parseInt(newInput.value);
npage>0&&host.excePage(npage);
}
pageBar.appendChild(newInput);
pageBar.appendChild(newGotoBtn)
.appendChild(host._createBarElm(6,'GO'));
}
host.pageBarDom = pageBar;
return host;
},
_createBarElm:function(type,attrs){ //生成控件上的按钮
var host = this;
var elm;
switch(type){
case 0://控件外框
elm = host._createElm('span',{id:host.id});
break;
case 1: //页码数字按钮
elm = host._createElm('span',{"class":"pageBar-page-btn"});
break;
case 2: //首页尾页
elm = host._createElm('span',{"class":"pageBar-firstLast-btn"});
break;
case 3: //上一页下一页
elm = host._createElm('span',{"class":"pageBar-nextPrev-btn"});
break;
case 4: //goto Button
elm = host._createElm('span',{"class":"pageBar-anyPage-btn"});
break;
case 5://input
elm = host._createElm('input',{"class":"pageBar-anyPage-input"});
break;
case 6://textNode
elm = host._createElm('textNode',attrs);
break;
}
return elm;
},
_createElm: function(elmName,attrs) {
//创建元素节点
var elm;
if(elmName=="textNode") {
if(arguments.length==1) {
attrs="";
}
elm = document.createTextNode(attrs.toString());
} else {
elm = document.createElement(elmName);
if(attrs) {
for(var attr in attrs) {
if(attr=="class"||attr=="className"){
elm.className = attrs[attr];
}else{
elm.setAttribute(attr,attrs[attr]);
}
}
} //end if(attrs)
}
return elm;
},
styleSheet:function(){//获取文档最后一个样式表
var host = this;
var styleSheets = document.styleSheets
if(!styleSheets.length){
document.getElementsByTagName("head")[0].appendChild(document.createElement("style"));
}
return styleSheets[styleSheets.length-1];
},
cssRules:function(styleSheet){//样式表的样式
host = this;
return styleSheet?(styleSheet.cssRules||styleSheet.rules):null;
},
addRule:function(styleSheet,selector,cssText,index){//增加一条样式
var host = this;
if(!styleSheet){ return host;}
var cssRules = host.cssRules(styleSheet);
if(index===undefined||index>cssRules.length){
index = cssRules.length;
}
if(styleSheet.insertRule){
styleSheet.insertRule(selector+'{'+cssText+'}',index);
}else{
styleSheet.addRule(selector,cssText,index);
}
return host;
},
removeRule:function(styleSheet,index){//删除一条样式
var host = this;
if(!styleSheet||!index){ return host;}
if(styleSheet.removeRule){
styleSheet.removeRule(index);
}else{
styleSheet.deleteRule(index);
}
return host;
},
createStyle:function(){
var host=this;
if(!host.options.defaultStyle){
return host;
}
var styleSheet = host.styleSheet();
var holderSelector = "#"+host.id;
host.addRule(styleSheet,holderSelector,host.barStyle['pageBar-hoder'])
.addRule(styleSheet,holderSelector+" span",host.barStyle['pageBar-all-btn'])
.addRule(styleSheet,holderSelector+" .pageBar-page-btn",host.barStyle['pageBar-page-btn'])
.addRule(styleSheet,holderSelector+" .pageBar-nextPrev-btn",host.barStyle['pageBar-nextPrev-btn'])
.addRule(styleSheet,holderSelector+" .pageBar-firstLast-btn",host.barStyle['pageBar-firstLast-btn'])
.addRule(styleSheet,holderSelector+" .pageBar-anyPage-btn",host.barStyle['pageBar-anyPage-btn'])
.addRule(styleSheet,holderSelector+" .pageBar-anyPage-input",host.barStyle['pageBar-anyPage-input'])
.addRule(styleSheet,holderSelector+" .pageBar-curPage-btn",host.barStyle['pageBar-curPage-btn'])
;
// if(!window.document.all){//非IE
host.addRule(styleSheet,holderSelector+" span:hover",host.barStyle['pageBar-all-btn-hover'])
.addRule(styleSheet,holderSelector+" span.pageBar-page-btn:hover",host.barStyle['pageBar-page-btn-hover'])
.addRule(styleSheet,holderSelector+" span.pageBar-nextPrev-btn:hover",host.barStyle['pageBar-nextPrev-btn-hover'])
.addRule(styleSheet,holderSelector+" span.pageBar-firstLast-btn:hover",host.barStyle['pageBar-firstLast-btn-hover'])
.addRule(styleSheet,holderSelector+" span.pageBar-anyPage-btn:hover",host.barStyle['pageBar-anyPage-btn-hover'])
.addRule(styleSheet,holderSelector+" span.pageBar-curPage-btn:hover",host.barStyle['pageBar-curPage-btn-hover'])
.addRule(styleSheet,holderSelector+":hover",host.barStyle['pageBar-hoder-hover'])
;
// }
return host;
}
}
return f;
})();
</script>
</head>
<body >
<span id="page_2" style="display: block;"></span>
<script>
var page2 = new PageNav({
container:'page_2',
pagecount:10,
pageKey:'page',
reload:true,
nextPrev:true, //是否显示上一页下一页按钮
firstLast:true,//是否显示首页尾页按钮
anyPage:true, //是否显示页码输入框和跳转按钮
dotted:true, //是否在省略页码出插入省略号
defaultStyle:true
},{k:9},function(a,b){alert(this.getGotoPage());});
/*
或
var page2 = new PageNav('page_2',15);
或
var page2 = new PageNav('page_2',15).show('page_2');
*/
</script>
</body>
</html>