摘要:,,uniapp在小程序中使用createIntersectionObserver时可能会遇到一些问题。创建Intersection Observer是为了监视元素在视口内的交叉状态,但在小程序环境中,由于视口大小和位置的变化,可能会出现无法准确监测元素交叉状态的情况。开发者需要熟悉API的使用方式,并考虑小程序特有的环境和限制,以确保createIntersectionObserver在小程序中正常运行。
优化前,我们通过在页面加载后获取元素节点的位置和滚动方式来实现相关功能,但这种方法的缺点显而易见,代码量大且监听scroll滚动会影响性能,官方也不推荐这种做法。
优化后,我们统一封装了Class类,全局处理createIntersectionObserver的监听,这样,无论是横向滚动还是竖向滚动到可视区内,都能实现精准埋点。
使用方法
options包含三个属性:
1、thresholds:一个数组,如[0.2,0.5,1],表示视口区域相交部分达到20%、50%、100%时都会触发监听。
2、initialRatio:默认为0,这个参数通常不需要改动。
3、observeAll:用于监听多个类名相同的数据。
IntersectionObserver包含四个方法:
1、relativeTo:以选中的节点作为容器区域,并根据传入的节点类名进行监听。
2、relativeToViewport:以传入的选择器节点只要出现在视口区域就会触发监听。
3、observe:传入需要监听的类名,回调函数包含一个参数result。
4、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 }) // 可根据需要调整margins参数 .observe(selector, (res) => { callback(res); }); } // 取消监听 off(selector) { if (!this.#listeners[selector]) return; this.#listeners[selector].disconnect(); Reflect.deleteProperty(this.#listeners, selector); } }
存在的问题与解决方案:
1、在微信小程序中,可以使用scss的穿透语法实现组件的类名监听。
2、支付宝小程序不支持穿透语法,建议使用官方推荐的createIntersectionObserver方法,但Vue3中无this关键字,需注意适配。
3、若已存在相同类名的监听,再次调用方法会报错,需先取消监听再创建。
4、页面隐藏或显示时,即使元素出现在当前可视区域也不会触发监听,针对此问题,可尝试重新初始化监听或寻找其他解决方案。
在小程序开发中,使用此API实现埋点数据上报,可以精准上报数据且不影响性能,在实际开发中,可能需要根据具体业务场景对API进行微调和优化。
还没有评论,来说两句吧...