我的编程空间,编程开发者的网络收藏夹
学习永远不晚

原生JS Intersection Observer API实现懒加载

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

原生JS Intersection Observer API实现懒加载

引言

前一阵子在做一个项目的时候,因为每组数据都要先通过很庞大的计算,才把计算后的结果 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 的时候,也会给你一个 ArrayArray 是所有正在监听的元素,我们可以从这些元素里的 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/%...

以上就是原生JS Intersection Observer API实现懒加载的详细内容,更多关于JS Intersection Observer API懒加载的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

原生JS Intersection Observer API实现懒加载

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

原生React怎么实现懒加载列表

这篇文章主要介绍了原生React怎么实现懒加载列表的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇原生React怎么实现懒加载列表文章都会有所收获,下面我们一起来看看吧。应用场景懒加载列表或叫做无限滚动列表,也是
2023-07-05

js怎么实现图片的懒加载

这篇文章给大家分享的是有关js怎么实现图片的懒加载的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。图片的懒加载是前端优化必须要掌握的东西,图片实现懒加载可以节省带宽又可以减轻我们网页的负荷。接下来我来记录一下我所掌
2023-06-14

原生+React实现懒加载(无限滚动)列表方式

这篇文章主要介绍了原生+React实现懒加载(无限滚动)列表方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-03-24

java懒加载的实现原理是什么

Java的懒加载(Lazy Loading)是一种延迟加载的策略,即在需要使用某个对象时才进行实例化和初始化,在之前不会占用额外的资源。懒加载的实现原理主要通过使用单例模式和双重检查锁定(Double-Checked Locking)来实现
2023-09-14

原生js怎么实现下拉刷新和上拉加载更多

本篇文章为大家展示了原生js怎么实现下拉刷新和上拉加载更多,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。JavaScript是什么JS是JavaScript的简称,它是一种直译式的脚本语言,其解释器
2023-06-26

前端图片懒加载的原理与3种实现方式举例

图片懒加载又称图片延时加载、惰性加载,即在用户需要使用图片的时候加载,这样可以减少请求,节省带宽,提高页面加载速度,相对的,也能减少服务器压力,下面这篇文章主要给大家介绍了关于前端图片懒加载的原理与3种实现方式的相关资料,需要的朋友可以参考下
2023-03-01

web前端图片懒加载的原理与实现方式有哪些

这篇文章主要讲解了“web前端图片懒加载的原理与实现方式有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“web前端图片懒加载的原理与实现方式有哪些”吧!一. 图片懒加载的目的大型网站如常
2023-07-05

单步调试理解webpack里通过require加载nodejs原生模块实现原理

在webpack和nodejs里,我们经常使用require函数加载原生模块或者开发人员自定义的模块。原生模块的加载,比如:const path = require("path");这个语句是webpack和nodejs应用里经常使用到的。
2023-06-03

编程热搜

目录