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:释放网页性能的黑科技

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值