• 判断元素出现在可视区域的方法


    我们经常遇到这样的需求——检测一个元素是否可见或者两个元素是否相交,如

    • 图片懒加载——当图片滚动到可见时才进行加载
    • 内容无限滚动——也就是用户滚动到接近内容底部时直接加载更多,而无需用户操作翻页,给用户一种网页可以无限滚动的错觉
    • 检测广告的曝光情况——为了计算广告收益,需要知道广告元素的曝光情况
    • 在用户看见某个区域时执行任务或播放动画

    Element.getBoundingClientRect()

    返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。

    缺点:事件监听和调用都是在主线程上运行,因此频繁触发、调用,造成浏览器频繁的重绘和回流,给网站带来相当大的卡顿

    Intersection Observer API

    window对象上有一个Intersection Observer API,
    它会注册一个回调函数,每当被监视的元素进入或者退出另外一个元素时 (或者 viewport ),或者两个元素的相交部分大小发生变化时,该回调方法会被触发执行。这样,我们网站的主线程不需要再为了监听元素相交而辛苦劳作,浏览器会自行优化元素相交管理。

    用法

    1. 创建一个 intersection observer
    • 创建一个 IntersectionObserver 对象,并传入相应参数和回调用函数,该回调函数将会在目标 (target) 元素和根 (root) 元素的交集大小超过阈值 (threshold) 规定的大小时候被执行。
    let options = {
      root: document.querySelector('#scrollArea'),
      rootMargin: '0px',
      threshold: 1.0
    }
    //回调函数只会在元素达到thresholds 规定的阈值时才会执行。
    let observer = new IntersectionObserver(callback, options);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    属性说明
    root必须是目标元素的父级元素。如果未指定或者为null,则默认为浏览器视窗。
    rootMargin用作 root 元素和 target 发生交集时候的计算交集的区域范围
    threshold目标 (target) 元素与根 (root) 元素之间的交叉比 (intersection ratio)取值在 0.0 和 1.0 之间。可以是单一的 number 也可以是 number 数组,默认值是 0 (意味着只要有一个 target 像素出现在 root 元素中,回调函数将会被执行)。该值为 1.0 含义是当 target 完全出现在 root 元素中时候 回调才会被执行。
    let callback =(entries, observer) => {
      entries.forEach(entry => {
     
        // entry.boundingClientRect  返回包含目标元素的边界信息
        //entry.rootBounds 返回根元素的边界信息
        // entry.intersectionRatio.  返回intersectionRect 与 boundingClientRect 的比例值。
        // entry.intersectionRect.  用来描述根和目标元素的相交区域。
        // entry.isIntersecting 
        //返回一个布尔值,如果目标元素与根相交,则返回true. 如果返回false, 变换是从交叉状态到非交叉状态。
        // entry.target 与根出现相交区域改变的元素
      });
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    2. 给定一个目标元素进行观察
    let target = document.querySelector('#listItem');
    observer.observe(target);
    //unobserve()	停止监听特定目标元素
    
    • 1
    • 2
    • 3

    请留意,你注册的回调函数将会在主线程中被执行。所以该函数执行速度要尽可能的快。如果有一些耗时的操作需要执行,建议使用 Window.requestIdleCallback() 方法

    3. 停止监听特定目标元素
    observer.unobserve(target);//例如图片懒加载时,加载完后即停止监听该元素
    
    • 1
    4. IntersectionObserver对象停止全部监听工作
    observer.disconnect();
    
    • 1

    缺点

    1. IntersectionObservers中的回调是在主线程中运行的,数据是异步传递的,这意味着我们的回调函数的调用优先级是比较低的,要等到浏览器空闲时。因此使用此api完成类似滚动相关的动画注定失败,因为数据在你使用它的时候已经过时了。

    IntersectionObservers deliver their data asynchronously, and your
    callback code will run in the main thread. Additionally, the spec
    actually says that IntersectionObserver implementations should use
    requestIdleCallback(). This means that the call to your provided
    callback is low priority and will be made by the browser during idle
    time. This is a conscious design decision

    2.api只是告诉我们元素什么时候进入视窗中,但是它没告诉我们
    元素是否被页面其他内容挡住了,或者元素的可视display是否被改成了其他效果
    or whether the Element’s visual display has been modified by any visual effects (transform, opacity, filter, etc)

    参考链接:
    https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API
    https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect
    https://web.dev/intersectionobserver-v2/
    https://developer.chrome.com/blog/intersectionobserver/#what-is-intersectionobserver-not-about

  • 相关阅读:
    测试4G网络是否正常的几种方法
    开发模式-敏捷开发
    泽众TestOne自动化测试平台,挡板测试(Mock测试)上线了!!
    gin+gorm+mysql
    Ansible之Playbooks的when语句
    解决Nacos服务器连接问题:一次完整的排查经验分享
    CMD常用操作
    AlGaN/GaN HFET 五参数模型
    计算机竞赛 题目:基于深度学习的中文汉字识别 - 深度学习 卷积神经网络 机器视觉 OCR
    @vue/cli脚手架的安装
  • 原文地址:https://blog.csdn.net/qq_38397338/article/details/126076744