• IntersectionObserver监听滚动事件


    前言

    我们在网页开发中,经常需要监听某个元素是否进入了可视区域内,从而进行相关操作,例如懒加载等;之前的做法大多都是通过监听 scroll 事件,通过获取目标元素的当前位置与视窗位置进行判断,通过这种方法需要监听 scroll 事件并且同时需要获取元素当前位置,会进行大量计算重绘等操作,可能会使页面卡顿,降低用户体验。
    IntersectionObserver 接口,可以代替我们手动监听元素,可以自动“观察”元素是否可见。

    一、完整测试代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <div style="width:1500px;height:1000px;background-color: red"></div>
        <img 
        src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.daimg.com%2Fuploads%2Fallimg%2F180314%2F1-1P314150U4.jpg&refer=http%3A%2F%2Fimg.daimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666259323&t=16e41dd0fbee7f16745d8fe5c12fe1ef"
        data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242332225H9-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666259108&t=372ec13b2f081b4b7194762f5630ff5c"
        >
        <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.daimg.com%2Fuploads%2Fallimg%2F180314%2F1-1P314150U4.jpg&refer=http%3A%2F%2Fimg.daimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666259323&t=16e41dd0fbee7f16745d8fe5c12fe1ef" data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1011%2F010QG05111%2F1F10Q05111-3.jpg&refer=http%3A%2F%2Fpic.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666259323&t=5ff4b80dd0506b088c02527b05409573"
        >
        <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.daimg.com%2Fuploads%2Fallimg%2F180314%2F1-1P314150U4.jpg&refer=http%3A%2F%2Fimg.daimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666259323&t=16e41dd0fbee7f16745d8fe5c12fe1ef" data-src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp08%2F39042223172520.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1666259323&t=7824d87aea3191b3166357ecbef5f4ec"
       >
        <script>
            const images = document.querySelectorAll('img');
            // 1. onscroll事件监听
    
            window.addEventListener('scroll',(e) => {
             images.forEach(image => {
                const imageTop = image.getBoundingClientRect().top;
                if(imageTop < window.innerHeight) {
                    const data_src = image.getAttribute('data-src');
                    image.setAttribute('src',data_src)
                }
                console.log('scroll')
             })
            })
            // 2. IntersectionObserver
            const callback = entries => {
                entries.forEach(entry => {
                    console.log(entry,'entry')
                    if(entry.isIntersecting) {
                        const image = entry.target;
                        const data_src = image.getAttribute('data-src');
                        image.setAttribute('src',data_src);
                        observer.unobserve(image);
                        console.log('触发')
                    }
                })
            }
            const observer = new IntersectionObserver(callback);
            images.forEach(image => {
                observer.observe(image)
            })
        </script>
    </body>
    </html>
    

    二. IntersectionObserver

    IntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗 (viewport) 交叉状态的方法。祖先元素与视窗 (viewport) 被称为根 (root)。
    当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦 IntersectionObserver 被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。

    1. 用法

    该API的调用非常简单:
    const io = new IntersectionObserver(callback, option);
    上面代码中,IntersectionObserver 是浏览器原生提供的构造函数,接受两个参数:
    (1)callback:可见性发现变化时的回调函数;
    (2)option:配置对象(可选)

    构造函数的返回值是一个观察器实例。实例一共有4个方法:
    (1)observe:开始监听特定元素
    (2)unobserve:停止监听特定元素
    (3)disconnect:关闭监听工作
    (4)takeRecords:返回所有观察目标的对象数组

    1.1 observe

    该方法需要接收一个target参数,值是Element类型,用来指定被监听的目标元素
    // 获取元素
    const target = document.getElementById(“dom”);

    // 开始观察
    io.observe(target);
    
    1.2 unobserve

    该方法需要接收一个target参数,值是Element类型,用来指定停止监听的目标元素
    // 获取元素
    const target = document.getElementById(“dom”);
    // 停止观察
    io.unobserve(target);

    三. 兼容性

    此api可能在部分设备及浏览器中不支持,这时我们可以降级使用 onscroll 事件,可以使用下面的函数来判断浏览器是否支持。

    const canUseIntersectionObserver = () =>
        'IntersectionObserver' in window &&
        'IntersectionObserverEntry' in window &&
        'intersectionRatio' in window.IntersectionObserverEntry.prototype;
    

    四. 参考资料

    探秘神奇的IntersectionObserver:释放网页性能的黑科技

  • 相关阅读:
    在互联网,摸爬滚打了几年,我悟了。面对如今经济形势,普通打工人如何应对?
    replace、replaceAll、replaceFirst的区别
    Volatile应用与底层原理
    Linux-网络配置、管理与基本应用
    HTML+CSS大作业:基于HMTL校园学校网页设计题材【我的学校网站】
    Mac本地安装PHP@7.4版本 - 2024
    MFC application : let‘s learn from the start
    四、Go中的条件判断和for循环
    【Transformer系列】关于Transformer的若干问题FAQ解析
    博客系统自动化测试
  • 原文地址:https://blog.csdn.net/m0_45093055/article/details/126960347