🎨🎨🎨国庆来唠唠,前端非常实用的监听API - Intersection Observer

先看效果。

➖ 上效果

第一个效果:图片懒加载

这些图片一开始是一个默认图片。当你滑过去的时候,它会加载出真实的图片。

第二个效果:加载更多

在瀑布流布局中,会加载一个小圈圈在转。当滑过去的时候,更多内容会被加载。

第三个效果:广告播放

这个广告在这里播放,但当你滑下去时,它会暂停。用户必须完整看到广告后,才能继续播放。


➖ 咋做

🔹 前期唠嗑

监听滚动条

以前咱做这玩意,可能第一反应就是监听这个滚动条。

看元素滚动的位置去判断。

缺点:

1、滚动事件不断触发,影响效率。

2、计算一些滚动位置,相对麻烦些。

现在咱有这个Intersection Observer,吃点好的,方便简洁相对好用,看看有些需求咱能不能用上吧。

官方文档

入口

🔹 切入做法

🔶 第一个效果 图片懒加载

🔻 创建观察

写页面:

html 复制代码
<div class="card-list">
    <div class="item">
      <img src="./default.png" alt="" data-src="https://picsum.photos/400/600?r=1" />
    </div>
    <div class="item">
      <img src="./default.png" alt="" data-src="https://picsum.photos/400/600?r=1" />
    </div>
    // ... 省略的代码 要100个item
 </div>

创建观察器

js 复制代码
const ob = new IntersectionObserver();

进行观察

js 复制代码
const ob = new IntersectionObserver();

ob.ovserve(xxx) // xxx代表被观察的dom元素。

这里xxx的dom就是我们要观察的,带有data-src图片的元素。

js 复制代码
const ob = new IntersectionObserver();

// 拿到图片dom,带有data-src的image
const imgs = document.querySelectorAll('img[data-src]');

// 然后呢,去循环这个图片,循环图片去观察每一个图片。
// 这个观察器,它是可以观察很多元素的,它可以不只观察一个元素。
imgs.forEach(img => {
  ob.observe(img);
})

// ob.observe(xxx)

观察了图了,达到条件后,叫它做什么这个回调函数也要告诉这个观察器。

js 复制代码
// 回调函数
const ob = new IntersectionObserver(() => {
  console.log('交叉了,运行这个回调函数。')
});

const imgs = document.querySelectorAll('img[data-src]');

// 循环图片去观察每一个图片。
imgs.forEach(img => {
  ob.observe(img);
})

再加配置。
三个参。

js 复制代码
const ob = new IntersectionObserver(() => {
  console.log('交叉了,运行这个回调函数。')
}, {
    root: null,
    rootMargin: '0px 0px 0px 0px',
    threshould: 0
});
🔻 细说配置

root:

就是观察的这个元素,跟谁在交叉。
默认值就是null。
默认的话就不用写。

rootMargin:

边距。

看它要交叉的那个元素的边距。

正数:比如10px,就是差10px要交叉了,就算交叉。

负数:比如-10px,就是交叉了还不行,要超过10px才去运行回调函数。

默认是'0px 0px 0px 0px'。默认可不写。

threshould:

观察的阈值。

范围是0到1。

默认是0。
两次回调。

头尾碰到阈值就调回调。

0是只要碰上。
1是完全离开。

🔻 回调参数

回调参数这里说的是entries。

它是个数组,实际就是把所有在被观察的元素以数组的形式告诉我们。

js 复制代码
// 回调函数
const ob = new IntersectionObserver((entries) => {

  for (const entry of entries) {
    if (entry.isIntersecting) {
      console.log('交叉了')
    }
  }
}, {
  threshould: 0
});

const imgs = document.querySelectorAll('img[data-src]');

imgs.forEach(img => {
  ob.observe(img);
})

entries里面是一个个对象,每个对象是一个INtersectionObserverEntry。

isIntersecting(布尔值)交叉了就true,否则false。

交叉之后呢,就把data-src的值给到src就可以了。

js 复制代码
// 回调函数
const ob = new IntersectionObserver((entries) => {

  for (const entry of entries) {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src; // 把data-src里的值,设置给img的src。
      ob.unobserve(img); // 通过这个函数去取消观察。以后就不需要观察它了。
    }
  }
  
}, {
  threshould: 0
});

const imgs = document.querySelectorAll('img[data-src]');

imgs.forEach(img => {
  ob.observe(img);
})

// ob.unobserve(img); // 做了之后就不做了,通过这个函数去取消观察。以后就不需要观察它了。

🔶 第二个效果 加载更多

js 复制代码
async function loadMoreImages (number = 10) {
  isLoading = false;
}

loadMoreImages(30);

const ob = new IntersectionObserver((entries) => {

  // 这里只观察它的第一个元素。
  const entry = entries[0]
  
  // 如果它已经有交叉了,那我们就去加载更多的10张图
  if (entry.isIntersecting) {
    loadMoreImages(10); // 就完事了。
  }
  
}, {
  threshold: 0,
});

// 那么它跟视口有交叉的情况下,就是能看见的情况下,给它设置一个阈值。
ob.observe(document.querySelector('.load-more')); 

🔶 第三个效果 广告不全就停

js 复制代码
const vd = document.querySelector('video');

const ob = new IntersectionObserver((entries) => {
  const entry = entries[0]
  if (entry.isIntersecting) {
    vd.play();
  } else {
    vd.pause();
  }
}, {
  threshold: 1 // 必须完整看到这个广告, 我才给你播放
});

ob.observe(vd);

threshold: 1:

只要这个视频被遮住了一点点,都给它停了,

要完整看到这个视频广告,才给你播。

threshold: 0.6:

如果这样子太变态太没人性,

就可以调一下这个threshold这个值。

不要设为1,

可以设为0.6这样。

这样子呢,

一开始可以看到这个视频,

到这个视频的60%被遮盖之后,就给它暂停。不超过60%就给它播。

➖ 大白话小结

IntersectionObserver 提供了一种高效的方式来处理元素与视口的交互,

避免了繁琐的滚动事件监控,

使得性能优化变得简单而直观。

☎️ 希望对大家有所帮助,本文有些地方可能考虑不够周到,有些纰漏,就当抛砖引玉,还望您海涵,如有错误,望不吝赐教,欢迎评论区留言互相学习。感谢阅读,祝您开发有乐趣。

相关推荐
子兮曰5 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰5 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万5 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝5 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋5 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁5 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95276 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大6 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师6 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学6 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端