微信小程式開發筆記4—— IntersectionObserver 用法詳解
阿新 • • 發佈:2018-11-04
看微信文件時看到這個很有趣的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
,用法基本於這個相同,但是它相對的參照物是頁面顯示區域。
以上就是內容,全是我自己的通過程式碼和例子進行的理解,如果有不對或者不完善的地方,歡迎交流。謝謝。