打个小广告哈,最近做了个小程序,来测测你的工作性价比吧~(微信扫码打开小程序即可)
看微信文档时看到这个很有趣的api,但是官方的文档和例子关于这个api的介绍都是很让人失望的,所以花了点时间了解了以下这个方法,做个记录,供参考。
简介
首先,我的理解是,这是一个观察器(废话),它用来监测目标对象与某个参照物的相交情况。什么是相交情况?通俗的说,就是两个区域有重叠(公共区域)了,类似与数学中的交集,不过这个是平面上的。
我们用官方给的一个简单的例子进行讲解:https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createIntersectionObserver.html ,点击最后的在开发者工具中预览即可。
演示图:
可以大致的看到,当小球出现/消失的时候,顶部的文字会跟着改变,右边的控制台也在打印着一些东西。下面我们就根据代码,来一谈究竟。
代码分析
首先是页面
<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>
可以看到,在scroll-view
中,定义了一个样式类为scroll-area
的区域,在这里面,又有三个子元素。分别是我们对应看到的文字(class=“notice”),和一个空白的占位元素(class=“filling”)和小球(class=“ball”)。
页面的样式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;
}
通过样式文件,我们可以看到,整个scroll-view
组件,占据屏幕高度是400rpx,但是其中的class=“scroll-area”
的元素,高度是1300rpx,也就是说,内部是可以上下滚动的。画了一张scroll-view的内部细节图,供参考:
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-view的相交情况。我们来看一下第一次相交的时候,日志打印的结果:
结果分析:
boundingClientRect
:目标边界。这个目标,就是我们的观察对象,可以看到刚开始相交的时候,它的位置情况。这个位置是相对于整个页面的,不是相对于参照元素的。top = 251(px) = scroll-view的高度(200px) + "小球消失/出现"message的高度(52px) - 相交高度(1px)
dataset
: 观察对象携带的数据。id
:观察对象的id,它与上面的dataset
多使用于一次观察多个对象的场景,用于区分不同的对象。intersectionRatio
相交比例:大于0的话表示两者有了交集,等于1的话表示两者已经完全相交。intersectionRect
相交区域:可以看出此时只有1px的高度有交集
。relativeRect
:参照区域的边界。通过其上下左右四个属性值可以看出它就是scroll-view
组件在页面中的位置。time
: 监测到两者相交时的时间戳,不太有用。
对应图解可以参考:
再看一下,从相交到没有交集,打印出来的结果:
结果分析:
boundingClientRect
:目标边界。此时top=-48,bottom=52
, 这个bottom的位置,刚好是“小球消失/出现”这个文字的所占高度52px。所以此时是刚好看不到小球。dataset
: 观察对象携带的数据。id
:观察对象的id,它与上面的dataset
多使用于一次观察多个对象的场景,用于区分不同的对象。intersectionRatio
相交比例为0,说明两者不相交。intersectionRect
相交区域。height = 0
说明 此时没有相交了。relativeRect
:参照区域的边界。作为参考物,它的值一般是不会变的。可以对比它于开始相交时一直没变,因为它就是一个scroll-view
的组件在页面上呈现出的位置信息。time
: 监测到两者相交时的时间戳,不太有用。
参考图解:
注意,上面两个图解中的黄色透明部分,是我们页面上可见的区域,不要弄混了
关于另一个api:relativeToViewport
,用法基本于这个相同,但是它相对的参照物是页面显示区域。
以上就是内容,全是我自己的通过代码和例子进行的理解,如果有不对或者不完善的地方,欢迎交流。谢谢。