记录微信小程序createIntersectionObserver()方法的使用

最近做的微信小程序项目涉及到了曝光埋点需求,即页面上某一模块或者某一些模块被滑动显示在屏幕上的时候,需要做相关的埋点记录,想到了之前用过小程序提供的createIntersectionObserver()方法做过滚动渐变处理,所以记录下createIntersectionObserver()的使用方法。

createIntersectionObserver通俗来讲主要是用于帮助监听页面上某一个对象是否与某一参照物相交,大多用来判断某一个对象是否出现在了可视区域。

官方文档地址:IntersectionObserver | 微信开放文档

一. 接口分析

1.创建‘监测’

wx.createIntersectionObserver(Object component, Object options)

Object component一般为this,也可为null
Object options
thresholds数值数组,代表相交比例的阈值,可有填写多个,取值范围 [0,1] ,当相交到达该阈值时会触发一次监听回调,默认为[0]。
initialRatio初始相交比例,如果方法调用时检测到的相交比例与这个值不相等且达到阈值,则会触发一次监听器的回调函数,默认为 0;
observeAll是否同时观测多个目标节点,默认为 fasle,从这里可以看出可以同时监听多个对象。

2.绑定参照物

这里提供了两个绑定参照物的方法:

IntersectionObserver.relativeTo(string selector, Object margins)

使用选择器指定一个节点,作为参照区域之一。

string selector

通过选择器来选择参照物

类似于css的但只包括:

id(#object)、class(.object)、子元素选择器(.parent > .child)、后代选择器(.parent  .child)、跨自定义组件的后代选择器(.parent >>> .child)以及支持多选择器的并集(#object, .object)

Object margins用来扩展(或收缩)参照节点布局区域的边界,可以适当的调整触发位置,包括left、right、top、bottom。


​​​​​​​IntersectionObserver.relativeToViewport(Object margins)

指定页面显示区域作为参照区域之一,Object margins同上。

3.设置监听

IntersectionObserver.observe(string targetSelector, function callback)

string targetSelectorselector 代表目标模块的选择器,即我需要监听的元素,当它和参考区域相交达到阈值比例时,会触发 callback 回调函数。
function callback

监听相交状态变化的回调函数,返回一个对象:

4.取消监听

IntersectionObserver.disconnect()

即停止监听,回调函数将不再触发。

二. 简单事例

通过官方提供的事例来稍作修改进行测试,通过方法来检测小球是否滚动到了指定区域:

wxmlcs

<view class="container">
  <view class="page-body">
    <view class="page-section message">
      <text wx:if="{{appear}}">
        小球出现
      </text>
      <text wx:else>
        小球消失
      </text>
    </view>
    <view class="page-section">
      <scroll-view class="scroll-view" scroll-y>
        <view class="scroll-area" style="{{appear ? 'background: #ccc' : ''}}">
          <text class="notice">向下滚动让小球出现</text>
          <view class="filling"></view>
          <view class="ball"></view>
        </view>
      </scroll-view>
    </view>
  </view>
</view>

wxss

.scroll-view {
  height: 400rpx;
  background: #fff;
  border: 1px solid #ccc;
  box-sizing: border-box;
}

.scroll-area {
  height: 1300rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: .5s;
}

.notice {
  margin-top: 150rpx;
}

.ball {
  width: 200rpx;
  height: 200rpx;
  background: #1AAD19;
  border-radius: 50%;
}

.filling {
  height: 400rpx;
}

.message {
  width: 100%;
  display: flex;
  justify-content: center;
}

.message text {
  font-size: 40rpx;
  font-family: -apple-system-font, Helvetica Neue,Helvetica,sans-serif;
}

 js

Page({
  data: {
    appear: false
  },
  onLoad() {
    this._observer = wx.createIntersectionObserver(this)
    this._observer
      .relativeTo('.scroll-view')
      .observe('.ball', (res) => {
        console.log(res);
        this.setData({
          appear: res.intersectionRatio > 0
        })
      })
  },
  onUnload() {
    if (this._observer) this._observer.disconnect()
  }
})

这个案例中红框内支持scroll-y上下滚动,且正中间有一个绿色小球,通过滚动操作监听绿色小球是否显示在红框内:

通过继续滚动,直到小球出现,发现会触发显示后调:

 继续滚动直到小球消失,发现会触发消失后调:

 监听多个的情况呢?首先我们来改一下代码,这里设置3种颜色的小球,同时为他们每一个球设置一个标题,希望在‘我’这个球显示的时候显示‘我’自己的标题,都没有显示则标题为‘啥也不是’:

wxml

<view class="container">
  <view class="page-body">
    <view class="page-section message">
      <text>
        {{title}}
      </text>
    </view>
    <view class="page-section">
      <scroll-view class="scroll-view" scroll-y>
        <view class="scroll-area" style="{{appear ? 'background: #ccc' : ''}}">
          <text class="notice">向下滚动让小球出现</text>
          <view class="filling"></view>
          <view class="ball green" data-item="我是小绿"></view>
          <view class="filling"></view>
          <view class="ball red" data-item="我是小红"></view>
          <view class="filling"></view>
          <view class="ball yellow" data-item="我是小黄"></view>
        </view>
      </scroll-view>
    </view>
  </view>
</view>

wxss

.scroll-view {
  height: 400rpx;
  background: #fff;
  border: 1px solid #ccc;
  box-sizing: border-box;
}

.scroll-area {
  height: 2800rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: .5s;
}

.notice {
  margin-top: 150rpx;
}

.ball {
  width: 200rpx;
  height: 200rpx;
  border-radius: 50%;
}

.green{
  background: #1AAD19;
}

.red{
  background: #ff0000;
}

.yellow{
  background: #fffb00;
}

.filling {
  height: 600rpx;
}

.message {
  width: 100%;
  display: flex;
  justify-content: center;
}

.message text {
  font-size: 40rpx;
  font-family: -apple-system-font, Helvetica Neue,Helvetica,sans-serif;
}

js

Page({
  data: {
    title: "啥也不是"
  },
  onLoad() {
    this._observer = wx.createIntersectionObserver(this,{observeAll:true})
    this._observer
      .relativeTo('.scroll-view')
      .observe('.ball', (res) => {
        console.log(res);
        if(res.intersectionRatio){
          this.setData({
            title: res.dataset.item
          })
        }else{
          this.setData({
            title: "啥也不是"
          })
        }
      })
  },
  onUnload() {
    if (this._observer) this._observer.disconnect()
  }
})

最后效果:

 

 

 最后需要注意一下,observerAll 只能观测已经存在的元素,假如是动态加载列表,则无法观测到之后添加的元素,这种情况与元素渲染的慢的情况可以通过设置setTimeout来等待元素渲染完成后开始监听,最后不需要的记得disconnect()。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值