一、分批加载
当前端在渲染dom元素时,数据多的时候渲染非常慢。并且很容易造成页面卡死,解决这个问题通常是用分页来解决的。
分页有两种方式:1、后台进行分页,前端通过传参的方式每次请求接口进行分页。2、前台进行分页,请求一次接口返回所有的数据,前端通过js进行分页。
本文所实现的是:请求一次接口返回所有数据,通过js将所有的数据进行二次分组,分割成每10个(或多个)一组,加载时,先加载一部分,当滚动条滚动时再加载另一部分。这样做:可以在返回数据之后即刻加载出内容,大大提高了用户的浏览性能。
下图是对数据重新分组的核心代码:
二、模糊查询
一些业务要求实现搜索查询的功能。这种功能实现也是两种方式:1、后台进行模糊查询,前端调用接口传递相应的参数即可。2、前端进行模糊查询,通过对所有的数据中相应的字段进行正则匹配,将匹配成功的数据放在一个新的数组中,进行渲染。
下图是判断数据和输入内容是否匹配的代码:
三、下面是结合分批加载和模糊查询所做的一个demo
demo地址:https://download.youkuaiyun.com/download/hhy1006894859/10856202
1、先引入jquery
2、本文所用到的数据为本地的json文件,需要自己模拟数据
代码:
js:
var totalArr = [];// 总数组,用来存放分割完毕的数组
var count = 10;// 每10个为一组
var totalArrIndex = null;// 用来展示加载总数组哪一项
var allArr = [];//allArr 均为请求接口获得的全部数据
var matchArr = [];// 匹配成功的所有数据存在的数组
var list = null;// 存放调用插件时所传来的list值
var repeatCount = 1;// 由于数据较少,测试的时候需要重复一下数据,这是重复的倍数,即最终数据为请求获得的数据乘以该倍数
// 获得全部的数据的方法
function getAllData(callback) {
$.ajax({
url:"../json/fpload.json",
type:"get",
dataType:"json",
success:function (res) {
console.log("成功",res);
// 模拟一些假数据,使总数据变得多一些
allArr = [];// 用来存放全部数据
for(var i=0;i<1*repeatCount;i++) {
allArr = allArr.concat(res.resultArray)
}
callback(allArr)// 全部数据返回
},
error:function (error) {
// console.log("失败",error)
}
})
}
// 将所有数据按照count进行分组
function sliceArr(allArr) {
totalArr = [];
for(var i=0;i<allArr.length;i+=count) {
totalArr.push(allArr.slice(i,i+count))
}
console.log("分割完后的数组",totalArr)
if(totalArr.length == 0) {
// 没有数据
nodatafun()
}
// 分割完数组之后进行首次加载数据,为了避免只加载第一条没有滚动条出现的问题,使用以下代码使得首次加载完后必定出现滚动条(或者加载完数据)。
for(var i=0;i<totalArr.length;i++) {
if($(document).height() <= $(window).height()) {
// 没有滚动条
loadData(totalArr[i])
totalArrIndex = i;
}else {
break;
}
}
}
// 在页面上渲染数据的方法
function loadData(arr) {
if(arr.length == 0) {
// 没有数据
}else {
for(var i=0;i<arr.length;i++) {
// 外层循环渲染card, (即渲染的是有多少个卡片)
var card = $('<div class="center card"></div>')
for(var j=0;j<list.length;j++) {
// 内层渲染li,渲染的是每个卡片的每列内容
card.append('' +
'<div class="center li">' +
'<span class="key">'+ list[j].msg +'</span>' +
'<span class="value">'+ arr[i][list[j].code] +'</span>' +
'</div>'
)
}
$('.cardWrap').append(card)
}
}
}
// 判断输入内容和某一项数据是否匹配的方法
function checkfun(value,str,callback) {
var reg = new RegExp(value);
var rdata = null;
if(str.match(reg) != null) {
// 匹配成功
rdata = 1;
}else {
// 没有匹配到
rdata = -1
}
callback(rdata)
}
// 点击搜索时所调用的方法
function searchfun(callback) {
matchArr = [];// 先置空存放匹配数据的数组
var value = $('.search input').val();
for(var i=0;i<allArr.length;i++) {
for(var j=0;j<list.length;j++) {
var isbreak = null;// 判断是否跳出本层循环
checkfun(value,allArr[i][list[j].code],function (flag) {
if(flag>0) {
// 匹配成功
matchArr.push(allArr[i]);
isbreak = true;
}else {
// 没有匹配到
isbreak = false;
}
})
if(isbreak) {
break;
}
}
}
callback()
}
// 清空页面数据的方法
function cleardata() {
$('.cardWrap').empty();
}
// 加载没有数据的方法
function nodatafun() {
$(".cardWrap").append('' +
'<span class="nodata">当前没有数据呦!</span>'
)
}
// 显示loading
function showload() {
$('.loadingWrap').show();
}
// 隐藏loading
function hideload() {
setTimeout(function () {
$('.loadingWrap').hide();
},500)
}
let cardPlugin = function(obj) {
showload();// 初始的时候先显示loading
list = obj.list;
$(function () {
// 获得全部的数据
getAllData(function (allArr) {
console.log("接口获得的所有数据",allArr)
cleardata();// 清空数据
hideload();// 隐藏loading
sliceArr(allArr)// 分割数组并进行第一次的加载
})
})
$(function () {
// 滚动条滚动进行加载数据
$(document).scroll(function () {
console.log(totalArrIndex)
var bottom = $(document).height() - $(document).scrollTop() - $(window).height();
if(bottom<600) {
// 设定一个界限,开始加载新的数据
totalArrIndex++;
if(totalArrIndex >= totalArr.length) {
// 滚动太快,下标超过了数组的长度
totalArrIndex = totalArr.length
return;
}
loadData(totalArr[totalArrIndex])
}
})
})
$(function () {
// 点击搜索进行模糊查询
$("body").on("click",".search button",function () {
showload();//显示loading
searchfun(function () {
console.log("匹配成功的数组",matchArr)
cleardata();// 清空数据
hideload();// 隐藏loading
sliceArr(matchArr)
})
})
})
}
css:(sass)
$card_w:6rem;// card的宽度
$card_bg:#ffffff;// card的背景颜色
$card_rd:0.08rem;// card的圆角
$card_liw:5.6rem;// 每一项的宽度
$card_liminh:0.8rem;// 每一项的最小高度
$card_fz:0.24rem;// card的文字大小
$card_liborcolor:#cccccc;// 每一项的下边框的颜色
$card_keycolor:#4d4d4d;// key的颜色
$card_valuecolor:#808080;// value的颜色
$card_keyminw:2.5rem;// key的最小宽度
$card_mb:0.2rem;// card的marginbottom
$card_nodata_fz:0.24rem;// 没有数据时的文字大小
$card_nodata_color:#4d4d4d;// 没有数据时的文字颜色
$card_search_h:0.5rem;
$load_mt:2rem;// 整个loading的margintop
$load_span:0.2rem;// loading小球的宽高
$load_spanmr:0.3rem;// loading小球间的间距
$load_spanbg:#ffffff;//loading小球的颜色
$box_width:6.4rem;// container的最大宽度和nav的宽度
$body_bg:#f0f0f0;// 四个子页面中body的背景颜色
@mixin border_bottom($color) {
& {
position: relative;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
border-bottom: 1px solid $color;
transform-origin: 0 0;
padding: 1px;
box-sizing: border-box;
pointer-events: none;
}
&:last-child:before {
border-bottom:none;
}
}
@media (-webkit-min-device-pixel-ratio:1),(min-device-pixel-ratio:1) {
&:before {
width: 100%;
height: 100%;
transform: scale(1);
}
}
@media (-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2) {
&:before {
width: 200%;
height: 200%;
transform: scale(0.5);
}
}
@media (-webkit-min-device-pixel-ratio:3),(min-device-pixel-ratio:3) {
&:before {
width: 300%;
height: 300%;
transform: scale(0.333);
}
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 100px;
}
body {
padding-top: $card_search_h;
background: #f0f0f0;
.search {
//border: 1px red solid;
position: fixed;
top: 0;
left: 50%;
width: $card_w;
margin-left: -$card_w/2;
height: $card_search_h;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-right: 0.2rem;
background: #f0f0f0;
z-index: 100;
}
.cardWrap {
//border: 1px red solid;
span.nodata {
display: block;
//border: 1px red solid;
font-size: $card_nodata_fz;
text-align: center;
color: $card_nodata_color;
}
}
.center {
display: block;
margin: 0 auto;
}
.card {
//border: 1px red solid;
width: $card_w;
background: $card_bg;
border-radius: $card_rd;
margin-bottom: $card_mb;
//height: 100px;
.li {
width: $card_liw;
min-height: $card_liminh;
//border-bottom: 1px #cccccc solid;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
font-size: $card_fz;
@include border_bottom($card_liborcolor);
span.key {
color: $card_keycolor;
width: $card_keyminw;
//border: 1px red solid;
padding-left: 0.1rem;
}
span.value {
color: $card_valuecolor;
//flex: 1;
width: $card_liw - $card_keyminw;
//border: 1px red solid;
padding-left: 0.1rem;
padding-right: 0.1rem;
}
}
}
// loading动画效果
.loadingWrap {
//border: 1px red solid;
position: fixed;
top: 0;
left: 50%;
margin-left: -$box_width/2;
width: $box_width;
height: 100%;
background: $body_bg;
z-index: 80;
display: block;
.loading{
//width: 150px;
//height: 15px;
margin: 0 auto;
margin-top:$load_mt;
//border: 1px red solid;
display: flex;
justify-content: center;
align-items: center;
span {
//border: 1px red solid;
display: inline-block;
width: $load_span;
height: $load_span;
margin-right: $load_spanmr;
border-radius: 50%;
background: $load_spanbg;
-webkit-animation: load 1.04s ease infinite;
&:last-child {
margin-right: 0px;
}
&:nth-child(1) {
-webkit-animation-delay:0.13s;
}
&:nth-child(2) {
-webkit-animation-delay:0.26s;
}
&:nth-child(3) {
-webkit-animation-delay:0.39s;
}
&:nth-child(4) {
-webkit-animation-delay:0.52s;
}
&:nth-child(5) {
-webkit-animation-delay:0.65s;
}
}
}
}
@-webkit-keyframes load{
0%{
opacity: 1;
-webkit-transform: scale(1.3);
}
100%{
opacity: 0.2;
-webkit-transform: scale(.3);
}
}
}
html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../css/fpload.css">
<title>分批加载</title>
</head>
<body>
<div class="search">
<input type="text">
<button>搜索</button>
</div>
<div class="cardWrap">
<!--<div class="center card">-->
<!--<div class="center li">-->
<!--<span class="key">险种个人编号</span>-->
<!--<span class="value">0123456789</span>-->
<!--</div>-->
<!--<div class="center li">-->
<!--<span class="key">险种个人编号</span>-->
<!--<span class="value">0123456789</span>-->
<!--</div>-->
<!--<div class="center li">-->
<!--<span class="key">险种个人编号</span>-->
<!--<span class="value">0123456789</span>-->
<!--</div>-->
<!--</div>-->
</div>
<div class="loadingWrap">
<div class="loading">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
</body>
</html>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script type="text/javascript" src="../js/fpload.js"></script>
<script>
cardPlugin({
"list":[
{"msg":"序号","code":"RN"},
{"msg":"编号1","code":"AAB001"},
{"msg":"编号2","code":"AAC001"},
{"msg":"日期1","code":"AAE003"},
{"msg":"日期2","code":"AAE002"},
{"msg":"类别","code":"AAE140"},
{"msg":"金额","code":"AAC040"},
{"msg":"支付基数","code":"AAE018"},
{"msg":"支付总金额","code":"AAE020"},
{"msg":"个人金额","code":"AAE021"},
{"msg":"其他金额","code":"AAE022"}
]
})
</script>
所用到的json文件格式如下:
{
"count":105,
"resultArray":[
{
"AAB001":"400000000000",
"AAC001":"200000000000",
"AAE003":"197802",
"AAE140":"保险",
"AAE002":"199602",
"AAC040":"3529.5",
"AAE018":"3529.5",
"AAE020":"0",
"AAE021":"0",
"AAE022":"0",
"RN":"1"
}]}