懒加载:顾名思义,就是页面加载数据时候偷个懒先。
遇到的实际问题:当你检索或者后台查询的数据量规模很大的时候,页面全部加载出来相对耗时是很长的,这样就会显得页面特别不友好。
交代背景:目前做的一个项目中存在一个下拉检索的业务,一开始以为数据库中只有百张表左右,因此也没有考虑到那么多,后面当同事在现场实施的时候发现客户归档数据库存在10000张表,然后点击页面下拉检索时候,我是眼睁睁的数了20s才看到数据加载出来了,瞬间就感觉自己的产品做的不满意(一个看似小的问题可能影响整个项目交付)。所以还是要考虑更全面。
就不再bb这么多了,我们就进入详情讲解吧。
主要运用到这几个知识点:
1.input框下拉检索功能,可以模糊匹配过滤
2.setInterval的实际使用和停止
主要思路:数据量大,我们可以分批显示,也就是所谓的先出来的数据为后续的数据争取时间,也就是先富带后富。
技术点1:下拉检索,主要利用几个事件(点击,键盘按下抬起,失去焦点)
实现这个功能我们需要考虑以下几步:
一,先实现点击input框时候出现下拉数据,代码实现原理主要就是在原先的input框下面加一个div,然后再追加ul li (或者div),代码实现如下:
//计算input框的大小距离 var domWid=$(div).width()+2; var domHig=$(div).height()+2; //获取dom节点位置 debugger; var posival = $(div).offset(); var gleft = posival.left; var gtop = posival.top+domHig+2; var indexx = 0; $(div).css({marginBottom:"0"}).attr("autocomplete","off");//去除Input输入的缓存 $("#g2").remove(); $(".contain").after("<div id='g2' style=\"width:"+domWid+"px;position: absolute;border:1px solid #4D90FE;border-top: 0;background: #FFF;margin-top:0px;top:"
+gtop+"px;left:"+gleft+"px;overflow-y: auto;overflow-x:hidden;z-index:9999;display:none;\"><ul style=\"width:"+domWid
+"px;list-style:none;padding:0;margin:0;overflow: hidden;\"></ul></div>"); $(div).click(function(){ var divvalue = $(div).val(); if(divvalue == null || divvalue == ""){ $("#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 jslen = jsdata.length; var grpnum = parseInt(jslen/1000)+1; var mycars = new Array(grpnum); var _index = 0; for (var i = 0; i < jslen; i++) { var j = parseInt(i/1000); mycars[j]+="<li style=\"width:100%;float:left;line-height:"+domHig+"px;height:"
+domHig+"px;cursor:pointer;\">"+jsdata[lenflag]+"</li>" linum++; lenflag++; } debugger; var cnum = 0; var sint = setInterval(function(){ debugger; $("#g2 ul").append(mycars[cnum++]); console.log("cnum:"+cnum); if(cnum>grpnum){ clearInterval(sint); } },50); var ulnum = linum*domHig; debugger; if(ulnum>200){ $("#g2").css({ "height":'200px' }); }else{ $("#g2").css({ "height":ulnum+'px' }); } $("#g2 li:eq("+indexx+")").attr("class","activee"); $("#g2 ul li").on("click",function(){ $(div).val($(this).html()); $("#g2").css({'display':"none"}); }); }else{ $("#g2").css({'display':"none"}); } } });
二、针对数据删除时候模糊匹配,这个时候就要考虑回退键的按下事件,针对键盘按下事件里面可以做一个判断。如下代码所示:
$(div).keyup(function(event){ if(event.keyCode == 38 || event.keyCode == 40 || event.keyCode == 13){ return; } $(div).keydown(function(event){ 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就显示一次,这样会存在一个小的缺陷,滚动条会慢慢拉动,因为数据一直在加载,这样用户体验就很不错了。
for (var i = 0; i < jslen; i++) { var j = parseInt(i/1000); mycars[j]+="<li style=\"width:100%;float:left;line-height:"+domHig+"px;height:"+domHig+"px;cursor:pointer;\">"+jsdata[lenflag]+"</li>" linum++; lenflag++; } debugger; var cnum = 0; var sint = setInterval(function(){ debugger; $("#g2 ul").append(mycars[cnum++]); console.log("cnum:"+cnum); if(cnum>grpnum){ clearInterval(sint); } },50);
有需要实际例子demo的欢迎留言。