作者:神 Q 超人
译者:前端小智
起源:medium
有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。
前一阵子在做一个我的项目的时候,因为每组数据都要先通过很宏大的计算,才把计算后的后果 Render 到页面上,但这样就导致如果单页查出来的数据超过大略 5 笔,就会须要期待一段有感的工夫,能力看到后果呈现在画面上。
起初为了解决这差劲用户体验,就应用到的题目上说到的 Lazy Loading 来解决。简略说就是,尽管要显示的数据量有 10 笔,但因为一个页面大略只能出现 2 到 3 笔,那我就先计算那 2 到 3 笔数据而后显示就好,剩下的数据等使用者往下滚再持续显示,这样等待时间就不会太久。
而后身为一个前端工程师,再想到这个解法当前,当然就是上 Github 找一个简略又不便的组件来解决它 😂,而最初找到的 vue-scroll-loader 应用起来非常容易,代码也少少的,所以就在解决完 issue 后,看它外部是如何实现 Lazy Loading,于是就看到明天次要讲的 Intersection Observer API 啦!
Intersection Observer API
那 Intersection Observer API 到底是什麽?为什麽它能够用来实现 Lazy Loading 呢?以 MDN 的说法来说:
Intersection Observer API 提供了一种异步检测指标元素与先人元素或 viewport 相交状况变动的办法。
简略说的意思就是只有应用 Intersection Observer API,就可能监听指标的元素在画面上呈现或来到的时候,执行你交给它的 callback 办法。下方就来看看应用的形式吧!
应用办法
首先要有简略的 HTML 和 CSS,次要指标就是把 div 放在往下滚才会呈现的中央:
body {height: 1000px;}
.box {
width: 100px;
height: 100px;
background: #000;
position: absolute;
top: 500px;
}
<body>
<div class="box"></div>
</body>
接著咱们用 Intersection Observer API 的 observe
办法,把要监听的 div
当作参数传给它,并用 callback
让它能够在 div 呈现和来到的时候给个音讯:
const intersectionObserver = new IntersectionObserver(() => {console.log('hi'); }
);
intersectionObserver.observe(document.querySelector('.box')
);
执行的后果就会像这样子:
而 Intersection Observer API 在执行 callback
的时候,也会给你一个 Array
,Array
是所有正在监听的元素,咱们能够从这些元素里的 isIntersecting
来判断以后的元素是呈现在画面中,还是来到画面了:
const intersectionObserver = new IntersectionObserver((entries) => {if (entries[0].isIntersecting) {console.log('我進來了!');
} else {console.log('我又进来了!');
}
}
);
intersectionObserver.observe(document.querySelector('.box')
);
执行后果:
最初就是当你不再须要持续监听元素的时候,能够应用 unobserve
来解除监听,应用时就像监听用的 observe
一样,给它不须要再监听的元素:
intersectionObserver.unobserve(document.querySelector('.box')
);
以上就是 Intersection Observer API 的根本用法,当然还有其余比拟认真的设置(能够看 MDN 的介绍),但如果要实现一个简略的 Lazy Loading,那只有会上方的几种应用形式就绰绰有馀了!
Lazy Loading
Intersection Observer API 实现 Lazy Loading 的办法就是在数据列表的最初放个 loading
的小动画,接着只有去监听小动画,当它呈现在页面中的时候,用 Intersection Observer API 的 callback
载入更多数据。
首先一样先简略写个要显示数据的 <ul>
,和要监听的元素,这裡我就不做小动画了,间接用 Loading…
文字代替 😂:
<body>
<ul class="list"></ul>
<div class="loading">Loading...</div>
</body>
要留神监听的元素必须要在载入数据的最上面哦!不然它不会被监听到“呈现在页面上”了(这个下方会更具体阐明注意事项)。
JavaScript 的局部先贴代码,下方再来解释:
const data = Array.from(Array(200)).map((_value, index) => ` 第 ${index + 1} 筆資料 `
);
const render = () => {const list = document.querySelector('.list');
const LOAD_DATA_COUNT = 50;
const startLoadIndex = list.childNodes.length;
const endLoadIndex = startLoadIndex + LOAD_DATA_COUNT;
for (let i = startLoadIndex; i < endLoadIndex; i++) {if (data[i]) {const text = document.createTextNode(data[i]);
const li = document.createElement('li');
li.appendChild(text);
list.appendChild(li);
}
}
if (endLoadIndex >= data.length) {const loading = document.querySelector('.loading');
loading.style.display = 'none';
intersectionObserver.unobserve(loading);
}
};
render();
const intersectionObserver = new IntersectionObserver((entries) => {if (entries[0].isIntersecting) {setTimeout(render, 1000);
}
}
);
intersectionObserver.observe(document.querySelector('.loading')
);
- 先用循环产生 200 笔的假数据
- 写一个
render
的办法,把还没载入的数据循环加去,这里一次加 50 笔数据 - 在
render
内加完数据,去判断以后加到的index
有没有大于数据总数,如果有的话代表所有数据显示完了,因而暗藏loading
,并移除 Intersection Observer API 对loading
的监听 - 毕竟一开始画面上还是要有数据!所以先手动执行第一次
render
办法 - 用 Intersection Observer API 监听
loading
,只有一呈现在画面上(代表使用者看完目前的数据,就要在执行render
。这裡为了有真正render
的感觉,我用setTimeout
来提早1
秒
执行的成果就会像这样子:
然而还有一点要留神的中央,以上方的例子来说,如果 Intersection Observer API 因为 loading
呈现在页面中执行了 render,然而 render 后的数据量却不足以把 loading
移到画面外,那 loading
就会始终停留在画面中,而不是“呈现在画面中”,这麽一来,Intersection Observer API 也就不会触发 render
载入更多数据。
最初来看一下反对状况。ntersection Observe API 的反对度算不错了,但如果产品有要思考到 IE 的客户群就没方法用了。😅
最初还是感觉从开源我的项目外面以学到很多乏味的货色,也举荐大家能够在应用某些组件时候偷看一下背地的源码怎麽解决的。😂
~ 完,我是刷碗智,新的一年,咱们一起洗刷刷新!!
代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。
原文:https://medium.com/starbugs/%…
交换
有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq44924588… 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。