15821967367
打開客服菜單
當前位置 : 思捷智聯 > 小程序開發 > 小程序 swiper 如何多頁面高度自適應
小程序 swiper 如何多頁面高度自適應
時間 : 11-19 14:07 瀏覽量 : 13

輪播,這個概念只要做過 UI 的都不會陌生,盲猜市場上 90% 的應用都有這個需求,在 iOS 和 Android 上都有很完善的控件,比如 Android 的 ViewPager 和 iOS 的 UIScrollview。

小程序這么牛逼,肯定也要有控件支持這個特性啊, swiper 就這么誕生了。

但是 swiper 有一個很嚴重的問題,就是高度默認 150px,且不可以自適應內容調整高度。

這就有問題了,我現在有一個多 Tab 的頁面,最少高度要滿屏,還要超出內容可以往下滾動,此時就蒙蔽了,怎么給 swiper 設置高度呢?

首先看一下我搜索到的一些方法:

  1. 在初始化的時候獲取到屏幕的高度,然后將高度設置到 swiper 上,至于滾動的問題,在里面再嵌入一個 scroll-view

    這個問題有很多坑,首先 屏幕的高度要比內容區的高度大,這么設置以后就算內容較少,頁面也能滑動一點;其次,小程序的 scroll-view 在實現上拉加載更多的時候,坑更多。

  2. 每個 item 的高度都一致,根據 item 的數量和統一的高度計算出內容的高度,然后設置進去

    這個方案感覺完全是 zz 方案,局限性太大了

我的方案

一句話解釋:給 swiper-item 內部添加三個錨點,最上面一個,最下面一個,還有一個錨點始終位于屏幕最底下。根據這三個錨點計算出內容高度和內容顯示區高度。 PS:錨點,寬高為 0 的不可見的 view,用于獲取定位

如果還有不理解可以看下面這個示意圖:



這三個錨點的具體作用是用來計算 swiper 內容高度和 swiper 距離屏幕底部的具體,計算方式如下:

  1. 使用 swiper-item 內部的兩個錨點計算出內容區高度

  2. 通過屏幕底部和 swiper-item 頂部的錨點計算出離屏幕底部的距離

接下來看看代碼具體實現

代碼實現

page.wxml

<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>復制代碼

page.wxss

.anchor-top {
    width: 0;
    height: 0;
}

.anchor-bottom {
    width: 0;
    height: 0;
}

.anchor-screen-bottom {
    position: absolute;
    bottom: 0;
    width: 0;
    height: 0;
}復制代碼

page.js

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 的都添加兩個錨點,和之前一樣一個在上面一個在下面,在切換頁面的時候,根據當前頁面的錨點重新計算一下高度,然后設置進去。

只需要在原有基礎上改一下代碼:

page.wxml

<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>復制代碼

page.wxss

CSS 不需要改動

page.js

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()
        })
      })
	},
})復制代碼

實現效果

  1. swiper 的高度高度根據內容自適應

  2. swiper 的高度最小占滿屏幕,最大和內容一樣高(為了用戶滑動體驗(如果劃頁后高度突然變小,用戶在原來的位置就劃不回去了)

  3. 適配不同高度的頁面

這個方案是了實現為自己的需求而寫的,應該不適應全部的場景,不過希望可以為你提供一點思路。

感想

小程序里的坑真的很多,而且有些 API 設計的很奇怪,真的不知道當初開發人員懷著怎樣的心路歷程設計出的 API。

個人感覺小程序就是給前端新造了一個輪子,更新還很不及時,有很多陳年老 Bug,比如本文講的 swiper

前端娛樂圈發展這么快,感覺小程序可能會跟不上潮流。


標簽:
微信小程序開發

適用類型 : 企業展示型

適用行業 : 企業

案例編號 : 001

您可能還在找這些
cache
Processed in 0.006842 Second.
浙江20选5几点开奖