IntersectionObserver API实现图片懒加载、无限滚动

1、IntersectionObserver API

IntersectionObserver 可以用来自动监听元素是否进入了设备的可视区域之内,而不需要频繁的计算来做这个判断。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"

const observer = new IntersectionObserver(callback, option);

IntersectionObserver 是浏览器原生提供的构造函数,接受两个参数

  • callback:当可见性发生变化时的回调函数
  • option:配置对象(可选性)

构造函数的返回值生成的实例有四个方法:

  • observe:开始监听特定元素
  • unobserve:停止监听特定元素
  • disconnect:关闭监听工作
  • takeRecords:返回所有观察目标的对象数组

1.1、observe 方法

该方法需要接收一个target参数,值为Element类型,指定被监听的目标元素

// 获取dom元素
const target = document.getElementById("app")

// 开始观察 实例.observe(dom元素)
observer.observe(target);

1.2、unobserve 方法

该方法需要接收一个target参数,值是Element类型,用来指定停止监听的目标元素

// 获取dom元素
const target = document.getElementById("app")

// 开始观察 实例.observe(dom元素)
observer.unobserve(target);

1.3、disconnect 方法

该方法不需要接收参数,用来关闭观察器

// 关闭观察器
observer.disconnect();

1.4、takeRecords 方法

该方法不需要接收参数,返回所有被观察的对象,返回值是一个数组

// 关闭观察器
const observerList = observer.takeRecords();

1.5、callback 参数

目标元素的可见性发生变化时,就会调用观察器的回调函数callback
可见性变化:目标元素进入视口,目标元素完全离开视口

const observer = new IntersectionObserver((changes, observer) => {
   
  console.log(changes);  // 包括的目标元素
  console.log(observer); // 当前实例对象
});

1.6、 options

可以在1.5中的 console.log(observer) 看到

  • threshold: 决定了什么时候触发回调函数。它是一个数组,每个成员都是一个门槛值,默认为[0],即交叉比例(intersectionRatio)达到0时触发回调函数。用户可以自定义这个数组。比如,[0, 0.25, 0.5, 0.75, 1]就表示当目标元素 0%、25%、50%、75%、100% 可见时,会触发回调函数。
  • root: 用于观察的根元素,默认是浏览器的视口,也可以指定具体元素,指定元素的时候用于观察的元素必须是指定元素的子元素
  • rootMargin: 用来扩大或者缩小视窗的的大小,使用css的定义方法,10px 10px 30px 20px表示top、right、bottom 和 left的值

2、IntersectionObserverEntry 对象

changes数组中每一项都是一个IntersectionObserverEntry 对象
changes相关参数

  • boundingClientRect:目标元素的矩形区域的信息
  • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
  • isIntersecting: 布尔值,目标元素与交集观察者的根节点是否相交(常用)
  • isVisible: 布尔值,目标元素是否可见(不建议在生产环境中使用)
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
  • target:被观察的目标元素,是一个 DOM 节点对象(常用)
  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒

3、相关效果

我们可以通过IntersectionObserver 来做到与滚动相关的效果

3.1、图片懒加载

首先需要观察懒加载元素,然后等元素进入可视化区域后设置图片的spc。还可以结合 IntersectionObserver.rootMargin 实现提前加载图片,一般可以设置为 1~2倍浏览器窗口的视口高度

HTML部分

<body>
    <h1>JavaScript 的歷史及現況</h1>

    <p>1990 年,科學家 Tim Berners-Lee 在互聯網的基礎上發明了萬維網 (World Wide Web),World Wide Web
        這個詞在互聯網早期經常提到,還一直影響至今,大家記得網址開端一般都是以 www 起首的嗎?就是 World Wide Web 的簡寫。發明了
        www,從此我們可以在網上互傳檔案。但這個時候的只能通過命令行模式 (Command Mode) 存取網絡,而且只能顯示文字,顯然是不方便的。</p>

    <p>1992 年史上第一個圖形化的網頁瀏覽器 Mosaic 誕生,1994 年改名為 Netscape Navigator (網景) 並推出 1.0 版本,市場佔有率超過
        90%。由於當時的互聯網速度很慢,而且上網費昂貴,Netscape
        公司為了優化瀏覽體驗,覺得有必要研發一套腳本語言,是在瀏覽器端運行的。例如我們在一個網站登入會員,忘了填寫用戶名稱就點擊了「登入」,這是候網頁再次載入,才提醒需要填寫用戶名稱,這顯然晚了一點。瀏覽器應該可以在用戶點擊「登入」時就進行初步檢查,在檢查到錯誤時及時彈出提示訊息讓用戶修正。
    </p>

    <p>Netscape 公司對於這種基於瀏覽器的腳本語言的想法是:功能不需要太強,語法較簡單,容易學習和應用。公司聘請了 Brendan Eich 研發這個腳本語言,據說他只用了 10
        天,就設計好這個語言的第一版,最初命名為 Mocha,及後改名為 LiveScript。</p>

    <p>而據說當時 Sun 公司的 Java 語言相當受歡迎,出於市場推廣的原因,固意將這門語言與 Java 在名義上扯上關係(而實際上幾乎沒有)。Netscape 與 Sun 公司達成「合作協議」允許將 LiveScript 命名為
        JavaScript。大家還記得當時有 JavaApplet 這種瀏覽器插件嗎?JavaApplet 是 Sun 公司發展出來,真正使用 Java 語言編寫,在瀏覽器端運行的應用程式,當時期望 JavaScript
        的角色是像膠水一樣將各部份連接起來。後來 JavaApplet 失敗了,JavaScript 卻發揚光大了。</p>

    <p>1996 年 JavaScript 隨著 Netscape 2.0 正式推出。</p>

    <p>1996 年 8 月 Microsoft 仿效 Netscape,於自己的 IE 瀏覽器發展出一門與 JavaScript 相近的腳本語言,取命 JScript。一山不能藏二虎,Netscape 公司將
        JavaScript 提交給 ECMA International(歐洲電腦製造商協會)進行標準化,它就是 ECMAScript。不過基於歷史原因及市場原因,大家都習慣用 JavaScript
        這個名字而非 ECMAScript。我們現在說的 JavaScript ES5 / ES6 等等,ES 就是 ECMAScript 版本
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
IntersectionObserver是一种新的API,可以用于实现懒加载。懒加载是指在页面滚动时,只加载可视区域内的内容,而不是一次性加载所有内容。这样可以优化网页加载速度,提升用户体验。 下面是IntersectionObserver实现懒加载的步骤: 1. 创建一个IntersectionObserver对象:可以通过其构造函数创建。 2. 选取需要进行懒加载的图片或其他DOM元素,将其包裹在一个容器元素中。 3. 使用IntersectionObserver对象的observe方法来观察容器元素。 4. 在回调函数中获取到可见性变化的元素,如果元素进入可视区域,就将其src属性指向真实图片的地址,实现图片的懒加载。 下面是一个示例代码: ``` let lazyImages = document.querySelectorAll('.lazy-image'); let options = { root: null, // 窗口视图作为根元素 rootMargin: '0px', // 不添加边框 threshold: 0.1 // 当可见性达到10%时触发回调 }; let observer = new IntersectionObserver(function(entries, observer) { entries.forEach(entry => { if (entry.isIntersecting) { // 元素进入可见视图 let lazyImage = entry.target; lazyImage.src = lazyImage.dataset.src; observer.unobserve(lazyImage); // 取消观察 } }); }, options); lazyImages.forEach(lazyImage => { observer.observe(lazyImage); }); ``` 在上面的代码中,我们首先选取了所有带有lazy-image类的图片元素,然后创建了一个IntersectionObserver对象,指定了观察的根元素和触发回调的阈值。接着,我们遍历了所有图片元素,使用observe方法观察了每个元素。在回调函数中,我们判断元素是否进入了可视区域,如果是,就将该元素的data-src属性值赋给src属性,实现懒加载,然后取消对该元素的观察。最后,我们通过forEach方法将所有图片元素添加到IntersectionObserver的观察列表中。 注意,容器元素的宽高需要在CSS中指定,否则IntersectionObserver无法准确计算元素的可见性。同样,图片元素的真实地址需要通过data-src属性指定,而不是src属性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值