javascript 页码控件

<!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':"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':"45px;",
  'pageBar-nextPrev-btn-hover':"background-color:#23fdac;",
  'pageBar-firstLast-btn':"45px;",
  'pageBar-firstLast-btn-hover':"background-color:#da4587;",
  'pageBar-anyPage-btn':"30px;",
  'pageBar-anyPage-btn-hover':"background-color:#ad45ff;",
  'pageBar-anyPage-input':"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>

 
原文地址:https://www.cnblogs.com/ecalf/p/2788466.html