輪播,這個概念只要作過 UI 的都不會陌生,盲猜市場上 90% 的應用都有這個需求,在 iOS 和 Android 上都有很完善的控件,好比 Android 的 ViewPager 和 iOS 的 UIScrollview。前端
小程序這麼牛逼,確定也要有控件支持這個特性啊, swiper
就這麼誕生了。小程序
可是 swiper
有一個很嚴重的問題,就是高度默認 150px,且不能夠自適應內容調整高度。markdown
這就有問題了,我如今有一個多 Tab 的頁面,最少高度要滿屏,還要超出內容能夠往下滾動,此時就矇蔽了,怎麼給 swiper
設置高度呢?xss
首先看一下我搜索到的一些方法:this
在初始化的時候獲取到屏幕的高度,而後將高度設置到 swiper
上,至於滾動的問題,在裏面再嵌入一個 scroll-view
spa
這個問題有不少坑,首先 屏幕的高度要比內容區的高度大,這麼設置之後就算內容較少,頁面也能滑動一點;其次,小程序的 scroll-view
在實現上拉加載更多的時候,坑更多。設計
每一個 item 的高度都一致,根據 item 的數量和統一的高度計算出內容的高度,而後設置進去code
這個方案感受徹底是 zz 方案,侷限性太大了orm
一句話解釋:給 swiper-item 內部添加三個錨點,最上面一個,最下面一個,還有一個錨點始終位於屏幕最底下。根據這三個錨點計算出內容高度和內容顯示區高度。 PS:錨點,寬高爲 0 的不可見的 view,用於獲取定位xml
若是還有不理解能夠看下面這個示意圖:
這三個錨點的具體做用是用來計算 swiper 內容高度和 swiper 距離屏幕底部的具體,計算方式以下:
swiper-item
內部的兩個錨點計算出內容區高度swiper-item
頂部的錨點計算出離屏幕底部的距離接下來看看代碼具體實現
<view>
<swiper style="height: {{anchor.deviceHeight + 'px'}}">
<swiper-item>
<view class="anchor-top"></view>
<!-- 你的內容 -->
<view class="anchor-bottom"></view>
</swiper-item>
</swiper>
<view class="anchor-screen-bottom"></view>
</view>
複製代碼
.anchor-top {
width: 0;
height: 0;
}
.anchor-bottom {
width: 0;
height: 0;
}
.anchor-screen-bottom {
position: absolute;
bottom: 0;
width: 0;
height: 0;
}
複製代碼
Page({
data: {
anchor: {
deviceHeight: 0,
anchorTop: 0,
anchorBottom: 0,
anchorScreenBottom: 0
}
},
onReady: function() {
this.computeSwiperHeight(0)
},
computeSwiperHeight(pageIndex) {
let getSwiperHeight = () => {
let min = this.data.anchor.anchorScreenBottom - this.data.anchor.anchorTop;
let value = this.data.anchor.anchorBottom - this.data.anchor.anchorTop
return Math.max(min, value)
}
wx.createSelectorQuery()
.select('.anchor-screen-bottom')
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec(res => {
this.data.anchor.anchorScreenBottom = res[0].bottom
})
wx.createSelectorQuery()
.selectAll('.anchor-top')
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec(res => {
this.data.anchor.anchorTop = res[0].top
this.setData({
'anchor.deviceHeight': getSwiperHeight()
})
})
wx.createSelectorQuery()
.selectAll('.anchor-bottom')
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec(res => {
this.data.anchor.anchorBottom = res[0].bottom
this.setData({
'anchor.deviceHeight': getSwiperHeight()
})
})
},
})
複製代碼
固然,確定要適配每一個頁面的高度不同的狀況。方案也很簡單,屏幕底部的錨只須要一個了,給每一個 swiper-item 的都添加兩個錨點,和以前同樣一個在上面一個在下面,在切換頁面的時候,根據當前頁面的錨點從新計算一下高度,而後設置進去。
只須要在原有基礎上改一下代碼:
<view>
<swiper style="height: {{anchor.deviceHeight + 'px'}}" bindchange="swiperChange">
<swiper-item>
<view class="anchor-top"></view>
<!-- 你的內容 -->
<view class="anchor-bottom"></view>
</swiper-item>
<swiper-item>
<view class="anchor-top"></view>
<!-- 你的內容 -->
<view class="anchor-bottom"></view>
</swiper-item>
</swiper>
<view class="anchor-screen-bottom"></view>
</view>
複製代碼
CSS 不須要改動
Page({
data: {
anchor: {
deviceHeight: 0,
anchorTop: 0,
anchorBottom: 0,
anchorScreenBottom: 0
}
},
onReady: function() {
this.computeSwiperHeight(0)
},
swiperChange(e) {
this.computeSwiperHeight(e.detail.current)
},
computeSwiperHeight(pageIndex) {
let getSwiperHeight = () => {
let min = this.data.anchor.anchorScreenBottom - this.data.anchor.anchorTop;
let value = this.data.anchor.anchorBottom - this.data.anchor.anchorTop
return Math.max(min, value)
}
wx.createSelectorQuery()
.select('.anchor-screen-bottom')
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec(res => {
this.data.anchor.anchorScreenBottom = res[0].bottom
})
wx.createSelectorQuery()
.selectAll('.anchor-top')
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec(res => {
this.data.anchor.anchorTop = res[0][pageIndex].top
this.setData({
'anchor.deviceHeight': getSwiperHeight()
})
})
wx.createSelectorQuery()
.selectAll('.anchor-bottom')
.boundingClientRect()
.selectViewport()
.scrollOffset()
.exec(res => {
this.data.anchor.anchorBottom = res[0][pageIndex].bottom
this.setData({
'anchor.deviceHeight': getSwiperHeight()
})
})
},
})
複製代碼
swiper
的高度高度根據內容自適應swiper
的高度最小佔滿屏幕,最大和內容同樣高(爲了用戶滑動體驗(若是劃頁後高度忽然變小,用戶在原來的位置就劃不回去了)這個方案是了實現爲本身的需求而寫的,應該不適應所有的場景,不過但願能夠爲你提供一點思路。
小程序裏的坑真的不少,並且有些 API 設計的很奇怪,真的不知道當初開發人員懷着怎樣的心路歷程設計出的 API。
我的感受小程序就是給前端新造了一個輪子,更新還很不及時,有不少陳年老 Bug,好比本文講的 swiper
。
前端娛樂圈發展這麼快,感受小程序可能會跟不上潮流。
給我正在開發的小程序預熱一下~
歡迎關注~