RE : Javascript分页处理

背景:

调用PHP后端给的接口,以实现分页的功能。由于我是没造轮子的能力,所以翻了不少技术博客,经过整合才算完成整个分页功能。从一番查阅中,不难看出大概分为两种不同的分页:
一种是纯前端的,就是在一次性加载完所有数据以后,通过隐藏多出来的部分,之后根据按钮获取列表长度中的每一小段,来实现分页的效果;另一种是直接调用接口获取到每一小段数据后分页。第二种方法中,相当于后台已经为我们做了分页,前端只需要为每一个按钮设置不同的节点获取数据就行。此外由于第一种方法是一次性加载完全部数据,所以在数据量较大的情况下首次加载的时间也会变长。下面会把两种方法都罗列一下。

相关链接:

纯javascript实现分页(两种方法): http://www.lai18.com/content/438532.html?from=cancel
简单封装分页功能:pageView.js http://web.jobbole.com/87590/
利用JS生成分页式table: http://blog.sciencenet.cn/blog-448935-603809.html
JS实现的分页效果: http://www.kanqianduan.com/archives/469
纯js实现分页: http://www.cnblogs.com/jiechn/p/4095029.html

分页的处理分为两个部分,一个是内容的显示部分区域。一个是分页按钮区域。最后显示区域的部分按照 纯js实现分页 来改的,按钮区域按照 JS实现的分页效果 的分页思路,用ajax对接后端数据实现。对于按钮方面,其中主要就是关于if判断的思路,分布式完成每一个if。再改变每一个if中的效果,按照实际的UI稿要求做分页的按钮就可以了。
在这个项目中,由于后端给的接口不同,两种不同的加载方式都使用到了。

效果展示

现在先来说说按钮区域

<div class="pager"  id="pagination" name="pagination">
    <!--<li><a href="#">上一页</a></li>
    <li><a href="#" class="active">1</a></li>
    <li><a href="#">2</a></li>
    <li><a href="#">3</a></li>
    <li><a href="#">4</a></li>
    <li><a href="#">5</a></li>
    <li><a href="#">下一页</a></li>-->
</div>

HTML的部分就是这个样子,我们需要获取 pagination,然后在里面输出分页页签。并且提前写好active的样式。

window.onload = function (){

    ……
    page({
      id:"pagination",   //当前id
      nowNum:1,//当前页
      allNum:10, //显示总页妈
      callBack:function(pno){
      //回调函数,在这里写相关显示传参数,如对于列表页的展示
       ……

});

                  
function page(opt){
    

    if (!opt.id) {return false;}
                        
    var obj = document.getElementById(opt.id);         
    var nowNum = opt.nowNum || 1;//默认值1
    var allNum = opt.allNum || 5;//默认值5
                        
    var callBack = opt.callBack || function(){};
                        
    //显示    首页btn
    if(nowNum>=4 && allNum>=6){
    var oA = document.createElement("a");//创建a标签
    oA.href = "#1";//设置#的值
    oA.innerHTML = "首页"//输出内容
    obj.appendChild(oA);//添加oA
    }
    //显示    上一页btn
    if(nowNum>=2){
    var oA = document.createElement("a");
    oA.href = "#" + (nowNum -1);
    oA.innerHTML = "上一页"
    obj.appendChild(oA);
    }
                        
    //当总页数小于等于5的时候
    if (allNum<=5) {
    
    //总页数值为多少,输出多少按钮

    for (var i =1;i<=allNum;i++) {
    //创建a标签
        var oA = document.createElement("a");
        oA.href = "#"+i;
                                    
        //当前页码效果
        if (nowNum == i) {
            oA.className = "active";//新增样式
            oA.innerHTML = i;
        }
                                    
        //其他页码效果
        else{
            oA.innerHTML = i;
        }
                                    
        obj.appendChild(oA);
    }
    }
//当总页数大于5的时候
    else{
        for (var i =1;i<=5;i++) {
        var oA = document.createElement("a");
                //当当前按钮是1或者2时,会出现负数,需要控制
        if (nowNum == 1 || nowNum == 2) {
            
            oA.href = "#" + i;
                                          
            if (nowNum == i) {
                oA.className = "active";
                oA.innerHTML = i;
            }
        else{
            oA.innerHTML = i;
        }     
    }                                 
    //通过总页-当前页的结果,判断点击最后的按钮时,如何输出                                
    else if((allNum -nowNum) == 0 ||(allNum -nowNum) == 1){
                
        oA.href = "#" + (allNum - 5 + i);                                     

        if ((allNum -nowNum) == 0 && i==5) {
            oA.className = "active";
            oA.innerHTML = (allNum - 5 + i);
        }
        else if((allNum -nowNum) == 1 && i==4){
            oA.className = "active";
            oA.innerHTML = (allNum - 5 + i);
        }
        else{
            oA.innerHTML =(allNum - 5 + i);
        }                                         
    }
                                    
    else{
        oA.href = "#" + (nowNum - 3 + i);
                                          
        if (i==3) {//使当前页签始终处于中间
            oA.className = "active";
            oA.innerHTML =(nowNum - 3 + i);
        }
        else{
            oA.innerHTML = (nowNum - 3 + i);
        }
     }
        obj.appendChild(oA);
   }

 }                 
                        
    //显示    尾页btn  
    if((allNum - nowNum)>=3 && allNum >=6){
        var oA = document.createElement("a");
        oA.href = "#" + allNum;
        oA.innerHTML = "尾页"
        obj.appendChild(oA);    
    }
    //显示    下一页btn      
    if((allNum - nowNum)>=1){
        var oA = document.createElement("a");
        oA.href = "#" + (nowNum +1);
        oA.innerHTML = "下一页"
        obj.appendChild(oA);    
    }
                  
    //callBack函数执行
    callBack(nowNum,allNum);
    //ithead 为表格需要输出的内容
    var ithead = document.getElementById("idData");
    //获得表格的行数长度

    var num = idData.childNodes.length;
    //无数据如何输出
    if(num == 0){
        obj.style.display="none";
        var oB = document.getElementById("warning");
        oB.innerHTML = "当前无成员周报数据";
    }
    else{
        //给a添加点击事件
        var aA = obj.getElementsByTagName("a");
        for (var i =0;i<aA.length;i++) {
            aA[i].onclick = function(){
            var nowNum = parseInt(this.getAttribute("href").substring(1));
            obj.innerHTML = "";
                              
    page({//重新赋值
                                    
        id:opt.id,
        nowNum:nowNum,
        allNum:allNum,
        callBack:callBack
        });
                              
        return false;     
        };
      }
    }      
}

创建按钮的方式方法其实都是一样的,需要注意的是赋值和判断的问题。
而分页展示区域的代码则放在回调函数里。并且在此之前需要声明变量。
这里在成功获取了后台ajax数据以后,先需要确定一共有多少行数据,确定每页有多少行,该例子中每页5行,故使用 总行数/每页行数 = 总页数。因为可能并非整除,故需要使用 Math.ceil 向上取整。

$.ajax({
    type:"get",
    url:"/api/admin/show_weekly.php?session="+session_id,
    dataType:'json',              
    success:function(json){
        var num = json["data"].length;//JSON字符串的条数
        var pageSize = 5;    //每页显示行数 
        var page_num = Math.ceil(num/pageSize);   //总页数
        var page_now = page_num -(page_num-1);    //等于第一页 
  

为对象设置好变量值,回调函数中直接调用接口输出数据。

        page({
                              
        id:"pagination",   //当前id
        nowNum:page_now,//当前页
        allNum:page_num, //显示总页妈
        callBack:function(pno){
            var itable = document.getElementById("idData");
            $("#idData").html("");

            for (var i =0; i <num;i++) {
                                    
itable.innerHTML += "<tr><td>"+ group(json["data"][i].group_id)  + "</td>" +
                                "<td>"+ json["data"][i].name + "</td>" +
                                "<td>"+ json["data"][i].week_num + "</td>" +
                                "<td>"+ status(json["data"][i].status) + "</td>" +
                                "<td>"+ json["data"][i].text+ "</td></tr>";
                                                
            };

之前提到有一次性加载数据和后台处理以后调用接口分次加载两种处理数据的方式。如果调用的是第二种,下面代码可直接省略。以下为对于每页多出行数数据的处理。

            var totalPage = 0;   //   总页数      
                        
            //总共分几页
            if(num/pageSize>parseInt(num/pageSize)){
            totalPage = parseInt(num/pageSize)+1;
            }else{
             totalPage = parseInt(num/pageSize);
            }

            var currentPage = pno;//当前页数
            var startRow = (currentPage - 1) * pageSize +1;
            var endRow = currentPage * pageSize;
            endRow = (endRow >num)? num:endRow;
                
            for (var i=1;i<(num+1);i++) {
                var irow = itable.rows[i-1];
                if (i>=startRow && i <=endRow) {
                    irow.style.display = "table-row";
                } else{
                    //超出的部分隐藏掉

                    irow.style.display = "none";
                }
            }
          }
        });
      },                      

    error:function(json){
        if (json.error != null) {
            alert(json.error)
        }

        else{
            alert("缺少必要的参数或参数为非数字");
       }
    }
});

后台SQL控制的好,完全可以将数据的切割交由他们,比起一次性加载完所有数据,由后台来控制数据显然更合理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,462评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,019评论 4 62
  • 其实有没有想过主动放弃生命这个问题,我是真的没想过。因为我的浅薄,让我在真的认真去思考这个问题时,只会从自身出...
    zzzz_阅读 106评论 0 0
  • E3吕伟强#周检视0807-0813 百日目标检视 1、每天吃三个青蛙。基本完成,只是难度不够大。 2、坚持跑步,...
    强_2f26阅读 133评论 0 0
  • 面试是平时的一面镜子?真实的你一定要足够优秀,方法不在于多,真实的自己体现出来。 做一个遍历,把基本的浅拷贝是没有...
    Hathaway_桉阅读 397评论 0 0