zoukankan      html  css  js  c++  java
  • 简析分页逻辑

      今天所提到的就是一个关于分页逻辑的思考过程,是众多分页方式的一种,这里简单整理一下我的思考过程。

      首先,确定一种分页的模式,现在线上使用的风格种类也比较多。这里我确定的具备下面的特点:
      1.具有上一页、下一页、首页、尾页
      2.具备设置defaultPage页后显示省略号
      3.具备当前页前后步数设置step

      其次,整理思路,如何实现这个功能,然后进行拆解。
      1.具有上一页、下一页、首页、尾页,这个逻辑很简单
        首页、上一页:如果总页数大于一页,并且当前页数不是第一页,就可以展示上一页(或者说,可以让上一页可点击)
        尾页、下一页:思路和上一页差不多,如果总页数大于一页,并且当前页数下于总页数,就可以展示下一页(或者说让下一页可点击)

        //首页、上一页逻辑
        if(page_id == 1) {
            //不可操作的首页和上一页
        }else if(page_id > 1 && last_page > 1) {
            //可操作的首页和上一页
        }
        //尾页、下一页逻辑
        if(page_id == last_page) {
            //不可操作的首页和下一页
        }else if(last_page > 1 && page_id < last_page) {
            //可操作的尾页和下一页
        }


      2.具备设置defaultPage页后显示省略号,这个逻辑需要考虑一些特殊情况,比如说:总页数只有一页,当然不能进入省略号的逻辑了

    //threshold = step + 2; 临界值
    //pagesDefault最小是临界值的二倍减去1
    pagesDefault = parseInt(pagesDefault) > 2*threshold-1 ? 2*threshold-1 : 5;


      3.设置step,这个是分页最重要的逻辑,这块儿单独详细解释一下:

      首先判断总页数是否下于或等于defaultPage,下于的话就直接循环输出即可

        for(var i=1; i<=last_page; i++) {
            if(i == page_id) {
                tpl += '<li class="curent">'+i+'</li>';
            }else {
                tpl += '<li>'+i+'</li>';
            }
            
        }

      其次就是总页数大于defaultPage,这又是这个逻辑中,最复杂的一块儿。

      要想直接想清楚这块儿的处理逻辑其实挺绕的,我们运用简单的数学归纳法,进行一个归纳(以step=1为例)

      一共有n页,他有一下几种逻辑:
      page_id=1 1 2 ... n
      page_id=2 1 2 3 ... n
      page_id=3 1 2 3 4 ... n
      page_id=4 1 ... 3 4 5 ... n
      page_id=5 1 ... 4 5 6 ... n
      ...
      page_id=n-3 1 ... n-4 n-3 n-2 ... n
      page_id=n-2 1 ... n-3 n-2 n-1 n
      page_id=n-1 1 ... n-2 n-1 n
      page_id=n 1 ... n-1 n

      可以总结出来以下结论:
      1.step=1
      2.可以看出临界值是3,也就是threshold=step+
      3.以临界值处理1~threshold的逻辑

    //当前页下于等于临界值的时候,需要考虑当前页的下一位情况,展示省略号和尾页情况
        for(var i=1; i<=next; i++) {
            if(i == page_id) {
                tpl += '<li class="curent">'+i+'</li>';
            }else {
                tpl += '<li>'+i+'</li>';
            }
        }
        if(next <= last_page-1) {
            tpl += '<li>...</li>';
        }
        if(next != last_page) {
            if(last_page == page_id) {
                tpl += '<li class="curent">'+last_page+'</li>';
            }else {
                tpl += '<li>'+last_page+'</li>';
            }
        }

      4.一临界值处理n-threshold+1~n的逻辑

    //当前页大于n-threshold并且下于n的时候,需要考虑当前页的上一位情况,展示省略号和首页情况
        if(pre != 1) {
            if(1 == page_id) {
                tpl += '<li class="curent">1</li>';
            }else {
                tpl += '<li>1</li>';
            }
        }
        if(pre >= 2) {
            tpl += '<li>...</li>';
        }
        for(var i=pre; i<=last_page; i++) {
            if(i == page_id) {
                tpl += '<li class="curent">'+i+'</li>';
            }else {
                tpl += '<li>'+i+'</li>';
            }
        }

      5.中间部分逻辑,就是显示当前页的前后step页,然后是省略号,然后就是首页、上一页、下一页、尾页的逻辑了。这块儿比较简单

    //处理中间页
        tpl += '<li>1</li>';
        tpl += '<li>...</li>';
        for(var i=pre; i<=next; i++) {
            if(i == page_id) {
                tpl += '<li class="curent">'+i+'</li>';
            }else {
                tpl += '<li>'+i+'</li>';
            }
        }
        tpl += '<li>...</li>';
        tpl += '<li>'+last_page+'</li>';

      这样整个逻辑就大工告成了,例子中是用JS实现的逻辑,这个逻辑可以用在其他的编程语言中。

      下面是整个例子的代码,可以看看整理过程是什么样的。效果地址:http://cnblogs.sinaapp.com/demo/page.html?step=3&lastPage=20&pageID=10可以通过配置相关数据可以查看效果。

    <html>
    <head>
    <meta charset="utf-8">
    <title>分页逻辑</title>
    <style>
    .disabled{
        color:#ccc;
    }
    .curent {
        color:red;
    }
    </style>
    </head>
    <body>
    <ul id="pageWrapper"></ul>
    <script>
    var pageID = queryUrl()['pageID'];
    var pageEl = document.getElementById('pageWrapper');
    
    //调用
    var page = intoPage(10, pageID);
    pageEl.innerHTML = page;
    
    /**
     * 解析url
     * @param {String} [url] 地址,默认是当前地址
     * @return {Object} url参数对象 
     */
    function queryUrl(url) {
        url = url || location.href;
        var result = {};
        var reg = /(?:(w+)=(w+))+/ig;
        if(reg.test(url)){
            url.replace(reg, function(input, key ,val) {
                result[key] = val;
            });
        }
        return result;
    }
    
    /**
     * 生成分页
     * @param {Number} last_page 总页数
     * @param {Number} page_id 当前页码
     * @param {Number} [step] 步数 默认是1
     * @param {Number} [pageDefault] 完全显示的页码最小值 默认是 2*(step+2)-1
     * @return {String} li字符串
     */
    function intoPage(last_page, page_id, step, pagesDefault) {
        last_page = parseInt(last_page);
        page_id = parseInt(page_id);
        step = parseInt(step) || 1;
        var tpl = '';
        var threshold = step + 2; //临界值
        var pre = page_id - step;
        var next = page_id + step;
        pagesDefault = parseInt(pagesDefault) > 2*threshold-1 ? 2*threshold-1 : 5;
    
        if(page_id == 1) {
            tpl += '<li class="disabled">首页</li>';
            tpl += '<li class="disabled">上一页</li>';
        }else if(page_id > 1 && last_page > 1) {
            tpl += '<li>首页</li>';
            tpl += '<li>上一页</li>';
        }
    
        if(last_page <= pagesDefault) {
            for(var i=1; i<=last_page; i++) {
                if(i == page_id) {
                    tpl += '<li class="curent">'+i+'</li>';
                }else {
                    tpl += '<li>'+i+'</li>';
                }
                
            }
        }else {
            if(page_id <= threshold) {
                //处理起始页
                for(var i=1; i<=next; i++) {
                    if(i == page_id) {
                        tpl += '<li class="curent">'+i+'</li>';
                    }else {
                        tpl += '<li>'+i+'</li>';
                    }
                }
                if(next <= last_page-1) {
                    tpl += '<li>...</li>';
                }
                if(next != last_page) {
                    if(last_page == page_id) {
                        tpl += '<li class="curent">'+last_page+'</li>';
                    }else {
                        tpl += '<li>'+last_page+'</li>';
                    }
                }
            }else if(page_id > last_page-threshold) {
                //处理结束页
                if(pre != 1) {
                    if(1 == page_id) {
                        tpl += '<li class="curent">1</li>';
                    }else {
                        tpl += '<li>1</li>';
                    }
                }
                if(pre >= 2) {
                    tpl += '<li>...</li>';
                }
                for(var i=pre; i<=last_page; i++) {
                    if(i == page_id) {
                        tpl += '<li class="curent">'+i+'</li>';
                    }else {
                        tpl += '<li>'+i+'</li>';
                    }
                }
            }else {
                //处理中间页
                tpl += '<li>1</li>';
                tpl += '<li>...</li>';
                for(var i=pre; i<=next; i++) {
                    if(i == page_id) {
                        tpl += '<li class="curent">'+i+'</li>';
                    }else {
                        tpl += '<li>'+i+'</li>';
                    }
                }
                tpl += '<li>...</li>';
                tpl += '<li>'+last_page+'</li>';
            }
        }
        if(page_id == last_page) {
            tpl += '<li class="disabled">下一页</li>';
            tpl += '<li class="disabled">尾页</li>';
        }else if(last_page > 1 && page_id < last_page) {
            tpl += '<li>下一页</li>';
            tpl += '<li>尾页</li>';
        }
    
        return tpl;
    }
    
    </script>
    </body>
    </html>


  • 相关阅读:
    tomcat安装
    hadoop相关
    kafka Windows安装
    linux安装mysql
    linux安装redis
    linux安装jdk
    netcore kafka操作
    windows文件上传到linux服务器上
    SqlServer索引的原理与应用(转载)
    mssql表分区
  • 原文地址:https://www.cnblogs.com/xiaoheimiaoer/p/4588482.html
Copyright © 2011-2022 走看看