首页 > 技术文章 > 前端懒加载的实际应用,input下拉检索大量数据(万条以上)

b-code 2018-05-17 18:04 原文

懒加载:顾名思义,就是页面加载数据时候偷个懒先。

遇到的实际问题:当你检索或者后台查询的数据量规模很大的时候,页面全部加载出来相对耗时是很长的,这样就会显得页面特别不友好

交代背景:目前做的一个项目中存在一个下拉检索的业务,一开始以为数据库中只有百张表左右,因此也没有考虑到那么多,后面当同事在现场实施的时候发现客户归档数据库存在10000张表,然后点击页面下拉检索时候,我是眼睁睁的数了20s才看到数据加载出来了,瞬间就感觉自己的产品做的不满意(一个看似小的问题可能影响整个项目交付)。所以还是要考虑更全面。

就不再bb这么多了,我们就进入详情讲解吧。

主要运用到这几个知识点:

1.input框下拉检索功能,可以模糊匹配过滤

2.setInterval的实际使用和停止

主要思路:数据量大,我们可以分批显示,也就是所谓的先出来的数据为后续的数据争取时间,也就是先富带后富。

技术点1:下拉检索,主要利用几个事件(点击,键盘按下抬起,失去焦点)

实现这个功能我们需要考虑以下几步:

一,先实现点击input框时候出现下拉数据,代码实现原理主要就是在原先的input框下面加一个div,然后再追加ul li (或者div),代码实现如下:

 

二、针对数据删除时候模糊匹配,这个时候就要考虑回退键的按下事件,针对键盘按下事件里面可以做一个判断。如下代码所示:

//键盘抬起事件
        $(div).keyup(function(event){
            //键盘事件时候则关闭原先定时器,不然会受其异步性的影响
            clearInterval(setint);
            if(event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 13){
                return;
            }
            $("#g2").css({'opacity':'1'});
            var domval=$(div).val();
            if(domval!=="" && domval!==null){
                dataNotnull(div,jsdata,domHig,indexx,setintfilt);
            }else{
                debugger;
                $("#g2 ul").html("");
                if(jsdata.length>0 && typeof(jsdata)!=="undefined"){
                    $("#g2").css({display:"block"});
                    var columns="";
                    var linum = 0;
                    //执行清除操作
                    $("#g2 ul li").remove();
                    var strli = "";
                    var lenflag = 0;
                    var mycars = "";
                    var jslen = jsdata.length;
                    //懒加载主要核心点
                    setintnull = setInterval(function(){
                        for(var i =0;i<1000;i++){
                            if(lenflag<jslen){
                                mycars+="<li  style=\"width:100%;float:left;line-height:"+domHig+"px;height:"+domHig+"px;cursor:pointer;\">"+
                   jsdata[lenflag]+"</li>" lenflag++; linum++; }else{ break; } } romanceLi(mycars,linum,domHig,div,indexx); if(lenflag==jslen){ clearInterval(setintnull); romanceLi(mycars,linum,domHig,div,indexx); } },50); }else{ $("#g2").css({'display':"none"}); } } }); //键盘按下去的时候 $(div).keydown(function(event){ //键盘按下时候应该把所有的时间触发关闭 clearInterval(setint); clearInterval(setintfilt); clearInterval(setintnull); var li_length = $("#g2 ul li").length; var ulheight = li_length*domHig; //每页多少条 var perpagenum = 200/domHig; //共多少页 var pagenum = li_length/perpagenum; $("#g2 li:eq("+indexx+")").removeClass('activee'); //上下键按下时候的事件触发38-上 40-下 if(event.keyCode == 38){ indexx--; indexx = indexx < 0 ? li_length - 1 : indexx; }else if (event.keyCode == 40){ indexx++; indexx = indexx > li_length - 1 ? 0 : indexx; }else if(event.keyCode == 13){ $(this).val($("#g2 li:eq("+indexx+")").html()); $("#g2").css({'display':"none"}); } console.log(indexx); $("#g2 li:eq("+indexx+")").addClass('activee'); }); $(div).blur(function(){ $("#g2").css({'opacity':'0'}); setTimeout(function(){ $("#g2").css({'display':"none"}); },1000); });

 

 

三、这个时候我们可以模拟一些数据,我当时模拟了10万条数据来测试该功能

//模拟假数据数组
    var mycheck1=new Array();
    for (var i = 0; i < 100000; i++) {
        mycheck1[i] = i;
    };
    var domid = "#check";
    //自定义封装下拉检索方法(可各种地方复用)
    getcheck(mycheck1,domid);

大数据核心处理模块在第一段代码其实已经贴出来了,如下所示,我们可以先将数据封装在一个自定义数组中,然后针对数据中塞带<li>标签的字符串,最终逐段拼接在原先的ul后面,设置一个计时器,每50ms就显示一次,这样会存在一个小的缺陷,滚动条会慢慢拉动,因为数据一直在加载,这样用户体验就很不错了。

var strli = "";
                    var lenflag = 0;
                    var jslen = jsdata.length;
                    var mycars = "";
                    //懒加载主要核心点
                    setint = setInterval(function(){
                        for(var i =0;i<1000;i++){
                            if(lenflag<jslen){
                                mycars+="<li  style=\"width:100%;float:left;line-height:"+domHig+"px;height:"+domHig+"px;cursor:pointer;\">"+jsdata[lenflag]+"</li>"
                                lenflag++;
                                linum++;
                            }else{
                                break;
                            }

                        }
                        romanceLi(mycars,linum,domHig,div,indexx);
                        if(lenflag==jslen){
                            clearInterval(setint);
                            romanceLi(mycars,linum,domHig,div,indexx);
                        }
                    },50);

 

有需要实际例子demo的欢迎留言。

 

推荐阅读