zoukankan      html  css  js  c++  java
  • 分页之美

      实现网站上的分页功能,其实没有什么难度,只要逻辑不出差错就可以正常工作了。至于代码写的怎样也就很少有人关心了,今天把分页按照思路写了一下,然后再进行优化。当然无论写的功能有多少,我们总是希望要能够复用,下次就不用再写了。每次使用也不会出错,健壮性很强。最后呢就是任何一个新人能够在几分钟内读懂代码,维护性好。同时达到这些要求,那就是完美!

      这个分页的功能很一般,分别实现:第一页,最后一页,下一页,上一页,跳到某一页。主要涉及到的参数如下:

    1. rPerPage:每页记录数
    2. rCount:总记录数
    3. dCount:每次显示的可选择的页码(例如当前页为2时,有[1][2][3][4][5][6][7][8][9][10] 十个链接,当前页为14时,有[11]到[20]十个链接)

      在实现的时候,只实现最核心的东西,其它都用回调函数去让外部定制。这样每次使用时自由度也会很大。去掉任何与显示有关的东西,只做加减法。下面是Page类代码:

     1 function Page(rCount/*total records count*/,dispCount/*page count display each time*/,recordPerPage/*records count per page*/,callback,rcallback){
     2     this.rPerPage=recordPerPage;//records count per page
     3     this.pCount= Math.ceil(rCount/this.rPerPage);//total page count
     4     this.dCount=dispCount;//display page number count each time
     5     this.curIdx = 1;//current page index
     6     this.onchange=callback;
     7     this.onrender=rcallback;
     8 }
     9 Page.prototype.next = function(){
    10     this.toPage(this.curIdx+1);
    11 };
    12 Page.prototype.pre = function(){
    13     this.toPage(this.curIdx-1);
    14 };
    15 Page.prototype.first = function(){
    16     this.toPage(1);
    17 };
    18 Page.prototype.last = function(){
    19     this.toPage(this.pCount);
    20 };
    21 Page.prototype.toPage=function(idx){
    22     if(idx<1 || idx > this.pCount) return;
    23     this.curIdx=idx;
    24     if(this.onchange) this.onchange.call(this,idx);
    25     this.printp();
    26 };
    27 Page.prototype.printp=function(){
    28     var rg = Math.ceil(this.curIdx/this.dCount);
    29     var u=(rg-1)*this.dCount+1,
    30         l=Math.min(rg*this.dCount,this.pCount);
    31     var d = [];
    32     while(u!==l+1) d.push(u++);
    33     if(this.onrender) this.onrender.call(this,d);
    34 };

      我们看到其实做事情的就两个函数,一个是toPage,一个是printp,其中toPage顾明思义就是跳到指定页,其它的如第一页,上一页等等都调用他即可。他在设置当前页索引的同时调用了onchange函数,并把新的页面索引传给它。这个onchange是我们从外面传入的回调函数至于做什么这边也不用关心了,只要让他知道变化后的页码。另外一个函数printp主要是显示页码的链接的。同样也是在每次索引变化后更新它。并把最新的页码数组传给外部的回调函数。

      这样把Page做为一个类来使用,就可以达到复用的目的,做个简单的测试:

     1 var ctPage = new Page(240,10,10);
     2 ctPage.onchange = function(idx){
     3     console.log("current page:"+idx);
     4 };
     5 ctPage.onrender = function(pn){
     6     console.log("current display numbers:"+pn);    
     7 };
     8 var zxPage = new Page(50,12,11,function(idx){
     9     console.log("zx curPage is:"+idx);
    10 },function(pn){
    11     console.log("zx numbers:"+pn);
    12 });

      这样就初始化了两个分另叫做"ctPage"和"zPage"的对象,他们独立且互不影响。通过运行可以在控制台看到结果:

    current page:1
    current display numbers:1,2,3,4,5,6,7,8,9,10
    current page:18
    current display numbers:11,12,13,14,15,16,17,18,19,20
    current page:22
    current display numbers:21,22,23,24
    zx curPage is:2
    zx numbers:1,2,3,4,5

      我相信保持这个类的简单性,可以让他更好的工作。至于使用场景也没限制,例如在onchange时,加入一个具有ajax请求的回调函数,这样就可以使用在ajax分页中。虽然简单的测试可以通过,不知道在实际环境中工作怎样,所以边使用边改进,努力让他成为最美的分页。

      这次用了点时间为这个类写了一个小案例,我们先把上面的Page放到js文件pagination.js中,然后在页面中加入引用:

    <script src="pagination.js" type="text/javascript"></script>

      在页面中放入需要显示的容器:

    <div id="pager"></div>

      我们对这个分页做一个简单的样式:

    #pager a,#pager span{
        display: block;
        float: left;
        padding: 0.3em 0.5em;
        margin-right: 5px;
        margin-bottom: 5px;
    }
    #pager a{
        text-decoration: none;
        border: solid 1px #AAE;
        color: #15B;
    }
    #pager .current{
        background: #26B;
        color: #fff;
        border: solid 1px #AAE;
    }

      下面这段脚本主要把Page类与表现连接起来并绑定交互的事件:

    function makeBtn(type,text,clickEvt,scope,attr){
        if(!type || type==="") return;
        var tag = document.createElement(type);
        if(clickEvt)
            tag.onclick = function(e){clickEvt.call(scope,e.target.innerHTML);};for(var key in attr)
            tag.setAttribute(key,attr[key]);
    tag.innerHTML = text;
    return tag; } function dsp(nums){ var curIdx = this.curIdx, cont = document.getElementById("pager"), p = this,preBtn,nextBtn; cont.innerHTML = ""; cont.appendChild(makeBtn("a","first",p.first,p,{href:"#"})); cont.appendChild(makeBtn("a","prev",p.pre,p,{href:"#"})); nums.forEach(function(item){ if(item===curIdx) cont.appendChild(makeBtn("span",item,null,null,{class:"current"})); else cont.appendChild(makeBtn("a",item,p.toPage,p,{href:"#"})); }); cont.appendChild(makeBtn("a","next",p.next,p,{href:"#"})); cont.appendChild(makeBtn("a","last",p.last,p,{href:"#"})); } function handler(idx){ //do something like request data and update dom console.log("send request idx:"+idx); } var p = new Page(240,10,10,handler,dsp); p.first();

      效果图,貌似是最大众的样式:



      我们也很容易换一种样式:


      上面样式的css:

    #pager .current {
        background: #222;
        color: #FFF;
        border-color: #000;
        box-shadow: 0 1px 0 rgba(255,255,255,0.2), 0 0 1px 1px rgba(0, 0, 0, 0.1) inset;
        cursor: default;
    }
    #pager a:hover {
        text-decoration: none;
        background: #444;
    }
    #pager a{
          text-decoration:none;
    }
    #pager a,#pager span {
        float: left;
        color: #CCC;
        font-size:14px;
        line-height:24px;
        font-weight: normal;
        text-align: center;
        border: 1px solid #222;
        min-width: 14px;
        padding: 0 7px;
        margin: 0 5px 0 0;
        border-radius: 3px;
        box-shadow: 0 1px 2px rgba(0,0,0,0.2);
        background: #555; /* Old browsers */
        background: -moz-linear-gradient(top, #555 0%, #333 100%); /* FF3.6+ */
        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#555), color-stop(100%,#333)); /* Chrome,Safari4+ */
        background: -webkit-linear-gradient(top, #555 0%,#333 100%); /* Chrome10+,Safari5.1+ */
        background: -o-linear-gradient(top, #555 0%,#333 100%); /* Opera11.10+ */
        background: -ms-linear-gradient(top, #555 0%,#333 100%); /* IE10+ */
        background: linear-gradient(top, #555 0%,#333 100%); /* W3C */
    }
    #pager{
          padding: 20px 20px 15px 20px;
          background: #444;
          border: 1px solid #333;
          border-radius: 2px;
          height:35px;
          font-family:Arial, Helvetica, sans-serif;
    }

      上面代码中的handler作为回调函数,可以做一些与服务器的交互和界面的更新(一般不超过10行啦)。而dsp函数主要是维护页码等按钮,代码不到10行。而最上边的makeBtn用来生成按钮的通用函数,不算在此模块里面边,所以我们直接把Page作为模块引用,只负责数据,接着只需要把Page类与“View”连接起来。那么每次就写20行以下的代码,并且保持了最大的灵活性,更重要的是正确性。Less is more.

  • 相关阅读:
    Linux用户配置文件、口令配置文件、组配置文件
    Linux忘记Root密码怎么找回
    Linux运行级别及解释
    Maven获取resources的文件路径、读取resources的文件
    常见状态码100、200、300、400、500等
    JVM内存模型
    tcl使用小结
    MFQ&&PPDCS
    总结下自己在工作中有关联的TCP/IP协议
    二层交换机和三层交换机
  • 原文地址:https://www.cnblogs.com/mike442144/p/2883835.html
Copyright © 2011-2022 走看看