眾所周知,可以滑動(dòng)的 scroll 組件在移動(dòng)端非常的重要,幾乎每個(gè)頁面都要用到。
而小程序的 scroll-view 組件就比較坑了,非得指定一個(gè)高度才能正常使用。布局復(fù)雜的時(shí)候誰還給你算高度啊。。。
坑歸坑,沒辦法,還是得用……既然官方要求必須傳高度,那就想辦法計(jì)算吧。
先給個(gè)示例圖:
這是一個(gè)稍微復(fù)雜點(diǎn)的頁面,最上面是兩個(gè) tab 標(biāo)簽,每個(gè)標(biāo)簽的頁面是一個(gè)子組件。第二個(gè)子組件布局是上面一個(gè)標(biāo)題,下面是 scroll-view 。
再畫個(gè)解剖圖吧……
頁面分三部分,tab,title,scroll-view。不要忘了每個(gè)部分間還有 margin , 這里設(shè)置的是每個(gè) margin 都是 10px 。
所以要計(jì)算 scroll-view 的高度可以得出下面 公式 :
scroll-view 的高度 = 頁面可用高度 - tab高度 - title高度 - 10 - 10 復(fù)制代碼
為什么減兩個(gè) 10 呢?上面說了 10 是 margin 的距離, tab 與 title 有 10px 的 margin, title 與 scroll-view 也有 10px 的 margin 。
需要注意的是計(jì)算用的單位都是 px ,不是小程序的 rpx 。因?yàn)橄旅嬲{(diào)用接口獲取可用屏幕高度時(shí)得到的就是 px 。
上面的公式中的變量有:頁面可用高度, title 的高度, tab 的高度。
這里需要計(jì)算的就是 頁面可用高度 和 title 的高度,因?yàn)闉榱撕唵?nbsp;tab 的高度是寫死的 50px , 當(dāng)然不寫死也沒關(guān)系,在父組件中計(jì)算 tab 的高度傳給子組件就好。
下面正式開始計(jì)算
//計(jì)算 scroll-view 的高度 computeScrollViewHeight() { let that = this let query = wx.createSelectorQuery().in(this) query.select('.title').boundingClientRect(function(res) { //得到標(biāo)題的高度 let titleHeight = res.height //scroll-view的高度 = 屏幕高度- tab高(50) - 10 - 10 - titleHeight //獲取屏幕可用高度 let screenHeight = wx.getSystemInfoSync().windowHeight //計(jì)算 scroll-view 的高度 let scrollHeight = screenHeight - titleHeight - 70 that.setData({ scrollHeight: scrollHeight }) }).exec() }, 復(fù)制代碼
這里主要是通過小程序封裝的 API 來計(jì)算的。
wx.getSystemInfoSync() 可以得到設(shè)備的各種信息,關(guān)于高度的參數(shù)有兩個(gè),一個(gè)是屏幕高度 screenHeight ,一個(gè)是可使用窗口高度 windowHeight 。注意計(jì)算的時(shí)候要用 windowHeight ,這樣算出來的高度才是對(duì)的。 screenHeight 是手機(jī)的屏幕高度,包含了手機(jī)的狀態(tài)欄和小程序標(biāo)題欄。
有了可用屏幕高度,還需要元素的高度。計(jì)算元素高度小程序也提供了 API,參見WXML節(jié)點(diǎn)信息API。
具體用法看文檔就好了,精簡的使用步驟就是:
let query = wx.createSelectorQuery().in(this) query.select('.title').boundingClientRect(function(res) { //在這里做計(jì)算,res里有需要的數(shù)據(jù) }).exec() 復(fù)制代碼
注意在組件 component 里使用的話,要用 wx.createSelectorQuery().in(this) ,將選擇器的選取范圍更改為自定義組件component內(nèi)。(初始時(shí),選擇器僅選取頁面范圍的節(jié)點(diǎn),不會(huì)選取任何自定義組件中的節(jié)點(diǎn)。)
如果想同時(shí)測量多個(gè)節(jié)點(diǎn)的高度呢?
能計(jì)算單個(gè)當(dāng)然也能同時(shí)計(jì)算多個(gè)。如下:
computeScrollViewHeight() { let that = this let query = wx.createSelectorQuery().in(this) query.select('.search').boundingClientRect() query.select('.title-wrapper').boundingClientRect() query.exec(res => { let searchHeight = res[0].height let titleHeight = res[1].height let windowHeight = wx.getSystemInfoSync().windowHeight let scrollHeight = windowHeight - searchHeight - titleHeight - 30 - 5 - 50 this.setData({ scrollHeight: scrollHeight}) }) }, 復(fù)制代碼
有幾個(gè)節(jié)點(diǎn)就寫幾個(gè) query.select('.search').boundingClientRect() , 然后調(diào)用 query.exec() 執(zhí)行操作獲取節(jié)點(diǎn)信息的數(shù)組。
注意:調(diào)用封裝好的 computeScrollViewHeight() 的時(shí)機(jī)是在生命周期函數(shù)的 ready() 中,不能在 created() ,否則取不到數(shù)據(jù)。
參見Component構(gòu)造器
計(jì)算完成后如何使用呢?
<scroll-view scroll-y style='height: {{scrollHeight + "px"}}'></<scroll-view>
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)