小工具知识网

当前位置: 首页 > 行业知识 > uniapp在小程序中使用createIntersectionObserver的问题

行业知识

uniapp在小程序中使用createIntersectionObserver的问题

2026-11-09 02:26:43 来源:互联网转载

前言

之所以是用这个Api,主要是为了优化项目。这个不光是可以用来实现图片的懒加载,还特别契合用于项目中的埋点。

优化之前:在页面加载以后获取元素节点的位置+滚动方式来做的。缺点显而易见,代码量比较多,而且监听scroll滚动官方也不推荐,非常影响性能。

优化之后:统一封装Class类,全局统一存储并处理createIntersectionObserver的监听。封装以后可以实现,横向滚动以及竖向滚动到可视区内都可以做到精准埋点。

使用方法

options的三个属性:

  • thresholds:是一个数组,比如你可以设置[0.2,0.5,1]那么在视口区域相交部分达到20%、50%、100%都会触发监听。
  • initialRatio:默认是0,这个参数基本不用改动的。
  • observeAll:这个属性主要是用来监听多个类名一样的数据

    IntersectionObserver 4个的方法

    • relativeTo:以你选中的节点作为容器区域,并根据你传入的节点类名进行监听,当传入的类名出现在容器内就会触发。
    • relativeToViewport:以你传入的选择器节点只要出现在视口区域就会触发监听。
    • observe:传入需要监听的类名,回调函数 callback 包含一个参数 result
    • disconnect:取消监听,隐藏或者卸载可取消监听。

      vue3-代码示例

      vue3中因为没有this,使用getCurrentInstance()

      代码封装:

      class ScrollObserver {    #instance;    #listeners;    constructor() {        this.#instance = getCurrentInstance();        this.#listeners = {};    }    static createObserver(selector, thresholds, observeAll = false) {        // 存在已经有的类名,则会报错,需要先取消监听        if (this.#listeners[selector]) this.#listeners[selector].disconnect();        this.#listeners[selector] = uni.createIntersectionObserver(this.#instance, {            thresholds,            observeAll,        });        return this.#listeners[selector];    }    on(selector,callback,observeAll = false) {    // 这里的监听[]可根据业务情况自行调整,监听满足条件是会重复触发        this.constructor.createObserver(selector, [0, 0.2, 1], observeAll)            .relativeToViewport({ right: 10 })            .observe(selector, (res) => {                callback(res);            });    }    // 取消    off(selector){        if (!this.#listeners[selector]) return        this.#listeners[selector].disconnect();        Reflect.deleteProperty(this.#listeners, selector);    }}

      margins: 用来扩展(或收缩)参照节点布局区域的边界

      这里margin我是用的,{ right: 10 }。按照正常理解应该是当元素滑动到可视区域bottom以下才对,不过这个bottom是距离下边界的距离,相当于还是在元素内部。实际开发也可以修改参数进行微调测试。

      使用示例:

      // 实例化对象const emitter = new ScrollObserver();
      emitter.on('.example', (res) => {     if (res.intersectionRatio === 1) {// 业务代码 }     if (res.intersectionRatio === 0) {// 业务代码} });

      存在的问题

      • 微信小程序:可以使用scss >>> 穿透语法实现组件的类名监听
      • 支付宝小程序:不可以使用 >>>,目前没有更好的办法兼容,官方推荐使用this.createIntersectionObserver,不过vue3并没有this。
      • 对已存在监听的类名,方法会抛出错误,需要先取消监听,然后再重新创建。
      • 页面的onhide或者onshow以后,虽然是出现在了当前可视区域,这种情况是没有触发监听的。

        总结

        在小程序开发中,使用这个Api来实现埋点的数据上报,基本是相当精准的,而且不会对性能造成影响。

上一篇:手机导航源码轻松获取,全攻略助你开启导航之旅!

下一篇:怎么选亚马逊服务器地址?