溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

移動端滾動插件BetterScroll怎么用

發(fā)布時間:2021-09-11 08:40:13 來源:億速云 閱讀:216 作者:小新 欄目:開發(fā)技術

這篇文章給大家分享的是有關移動端滾動插件BetterScroll怎么用的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

讓滾動更流暢

在移動端,如果你使用過 overflow: scroll 生成一個滾動容器,會發(fā)現它的滾動是比較卡頓,呆滯的。為什么會出現這種情況呢?

因為我們早已習慣了目前的主流操作系統(tǒng)和瀏覽器視窗的滾動體驗,比如滾動到邊緣會有回彈,手指停止滑動以后還會按慣性繼續(xù)滾動一會,手指快速滑動時頁面也會快速滾動。而這種原生滾動容器卻沒有,就會讓人感到卡頓。

BetterScroll 的滾動體驗

試一試 BetterScroll 的滾動體驗吧。體驗地址

可以發(fā)現,在增加慣性滾動,邊緣回彈等效果之后,明顯流暢、舒服了很多。那么,這些效果是怎么實現的呢?

慣性滾動

BetterScroll 在用戶滑動操作結束時,還會繼續(xù)慣性滾動一段。首先看一下源碼中的 BScroll.prototype._end 函數,這是 touchend、mouseup、touchcancel、mousecancel 事件的處理函數,也就是用戶滾動操作結束時的邏輯。

BScroll.prototype._end = function (e) {
    ...
    if (this.options.momentum && duration < this.options.momentumLimitTime && (absDistY > this.options.momentumLimitDistance || absDistX > this.options.momentumLimitDistance)) {
      let momentumX = this.hasHorizontalScroll ? momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options)
        : {destination: newX, duration: 0}
      let momentumY = this.hasVerticalScroll ? momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options)
        : {destination: newY, duration: 0}
      newX = momentumX.destination
      newY = momentumY.destination
      time = Math.max(momentumX.duration, momentumY.duration)
      this.isInTransition = 1
    }
    ...
}

以上代碼的作用是,在用戶滑動操作結束時,如果需要開啟了慣性滾動,用 momentum 函數計算慣性滾動距離和時間。該函數,根據用戶滑動操作的速度和 deceleration選項 ——慣性減速來計算滾動距離,至于滾動時間,也是一個可配置的選項。

function momentum(current, start, time, lowerMargin, wrapperSize, options) {  
  ...
  let distance = current - start
  let speed = Math.abs(distance) / time
  ...
  let duration = swipeTime
  let destination = current + speed / deceleration * (distance < 0 ? -1 : 1)
  ...
}

邊緣回彈

超過邊緣時的回彈,有兩個處理步驟,第一步是滾動到超過邊界時速度要變慢,第二步是回彈到邊界。其中,第一步是在源碼的 BScroll.prototype._move 函數,這是 touchmove 和 mousemove 事件的處理函數,也就是在用戶滑動操作過程中的邏輯。

// Slow down or stop if outside of the boundaries
if (newY > 0 || newY < this.maxScrollY) {
    if (this.options.bounce) {
        newY = this.y + deltaY / 3
    } else {
        newY = newY > 0 ? 0 : this.maxScrollY
    }
}

第二步是調用BScroll.prototype.resetPosition函數,回彈到邊界。

BScroll.prototype.resetPosition = function (time = 0, easeing = ease.bounce) {
    ...
    let y = this.y
    if (!this.hasVerticalScroll || y > 0) {
      y = 0
    } else if (y < this.maxScrollY) {
      y = this.maxScrollY
    }
    ...
    this.scrollTo(x, y, time, easeing)
    ...
  }

流暢的滾動僅僅是基礎,BetterScoll 真正的能力在于:提供了大量通用 / 定制的 option 選項 、 API 方法和事件,讓各種滾動需求實現起來更高效。

如何應用于各種需求場景

下面,以結合 Vue 的使用為例,說一下 BetterScroll 在各種場景下的姿勢。

普通滾動列表

比如,有如下列表:

<div ref="wrapper" class="list-wrapper">
  <ul class="list-content">
    <li @click="clickItem($event,item)" class="list-item" v-for="item in data">{{item}}</li>
  </ul>
</div>

我們想要讓它垂直滾動,只需要對該容器進行簡單的初始化。

import BScroll from 'better-scroll'

const options = {
  scrollY: true // 因為scrollY默認為true,其實可以省略
}

 
this.scroll = new BScroll(this.$refs.wrapper, options)

對于 Vue 中使用 BetterScroll,有一個需要注意的點是,因為在 Vue 模板中列表渲染還沒完成時,是沒有生成列表 DOM 元素的,所以需要在確保列表渲染完成以后,才能創(chuàng)建 BScroll 實例,因此在 Vue 中,初始化 BScroll 的最佳時機是 mouted 的 nextTick。

// 在 Vue 中,保證列表渲染完成時,初始化 BScroll
mounted() {
   setTimeout(() => {
     this.scroll = new BScroll(this.$refs.wrapper, options)
   }, 20)
},

初始化之后,這個 wrapper 容器就能夠優(yōu)雅地滾動了,并且可以通過 BScroll 實例this.scroll使用其提供的 API 方法和事件。

下面介紹幾個常用的選項、方法和事件。

滾動條

scrollbar選項,用來配置滾動條,默認為 false。當設置為 true 或者是一個 Object,開啟滾動條。還可以通過 fade 屬性,配置滾動條是隨著滾動操作淡入淡出,還是一直顯示。

// fade 默認為 true,滾動條淡入淡出
options.scrollbar = true

// 滾動條一直顯示
options.scrollbar = {
  fade: false
}

this.scroll = new BScroll(this.$refs.wrapper, options)

具體效果可見普通滾動列表-示例。

下拉刷新

pullDownRefresh選項,用來配置下拉刷新功能。當設置為 true 或者是一個 Object 的時候,開啟下拉刷新,可以配置頂部下拉的距離(threshold)來決定刷新時機,以及回彈停留的距離(stop)

options.pullDownRefresh = {
  threshold: 50, // 當下拉到超過頂部 50px 時,觸發(fā) pullingDown 事件
  stop: 20 // 刷新數據的過程中,回彈停留在距離頂部還有 20px 的位置
}

this.scroll = new BScroll(this.$refs.wrapper, options)

監(jiān)聽 pullingDown 事件,刷新數據。并在刷新數據完成之后,調用 finishPullDown() 方法,回彈到頂部邊界

this.scroll.on('pullingDown', () => {
  // 刷新數據的過程中,回彈停留在距離頂部還有20px的位置
  RefreshData()
    .then((newData) => {
      this.data = newData
      // 在刷新數據完成之后,調用 finishPullDown 方法,回彈到頂部
      this.scroll.finishPullDown()
  })
})

具體效果可見普通滾動列表-示例。

上拉加載

pullUpLoad選項,用來配置上拉加載功能。當設置為 true 或者是一個 Object 的時候,可以開啟上拉加載,可以配置離底部距離閾值(threshold)來決定開始加載的時機

options.pullUpLoad = {
  threshold: -20 // 在上拉到超過底部 20px 時,觸發(fā) pullingUp 事件
}

this.scroll = new BScroll(this.$refs.wrapper, options)

監(jiān)聽 pullingUp 事件,加載新數據。

this.scroll.on('pullingUp', () => {
  loadData()
    .then((newData) => {
      this.data.push(newData)
  })
})

具體效果可見普通滾動列表-示例。

選擇器

wheel選項,用于開啟并配置選擇器。可配置選擇器當前選擇的索引(selectedIndex),列表的彎曲弧度(rotate),以及切換選擇項的調整時間(adjustTime)。

options.wheel = {
  selectedIndex: 0,
  rotate: 25,
  adjustTime: 400
}

// 初始化選擇器的每一列
this.wheels[i] = new BScroll(wheelWrapper.children[i], options)

具體效果可見選擇器 - 示例。

其中聯動選擇器,需要監(jiān)聽每個選擇列表的選擇,來改變其他選擇列表。

data() {
   return {
     tempIndex: [0, 0, 0]
   }
},
...
// 監(jiān)聽每個選擇列表的選擇
this.wheels[i].on('scrollEnd', () => {
  this.tempIndex.splice(i, 1, this.wheels[i].getSelectedIndex())
})
...
// 根據當前選擇項,確定其他選擇列表的內容
computed: {
  linkageData() {
    const provinces = provinceList
    const cities = cityList[provinces[this.tempIndex[0]].value]
    const areas = areaList[cities[this.tempIndex[1]].value]

    return [provinces, cities, areas]
  }
},

具體效果可見選擇器 - 示例中的聯動選擇器。

輪播圖

snap選項,用于開啟并配置輪播圖??膳渲幂啿D是否循環(huán)播放(loop),每頁的寬度(stepX)和高度(stepY),切換閾值(threshold),以及切換速度(speed)。

options = {
  scrollX: true,
  snap: {
    loop: true, // 開啟循環(huán)播放
    stepX: 200, // 每頁寬度為 200px
    stepY: 100, // 每頁高度為 100px
    threshold: 0.3, // 滾動距離超過寬度/高度的 30% 時切換圖片
    speed: 400 // 切換動畫時長 400ms
  }
}

this.slide = BScroll(this.$refs.slide, options)

具體效果可見輪播圖 - 示例。

特殊場景

除了普通滾動列表、選擇器、輪播圖等基礎滾動場景,還可以利用 BetterScroll 提供的能力,做一些特殊場景。

索引列表

索引列表,首先需要在滾動過程中實時監(jiān)聽滾動到哪個索引的區(qū)域了,來更新當前索引。在這種場景下,我們可以使用probeType選項,當此選項設置為 3 時,會在整個滾動過程中實時派發(fā) scroll 事件。從而獲取滾動過程中的位置。

options.probeType = 3
this.scroll = new BScroll(this.$refs.wrapper, options)

this.scroll.on('scroll', (pos) => {
  const y = pos.y

  for (let i = 0; i < listHeight.length - 1; i++) {
    let height1 = listHeight[i]
    let height2 = listHeight[i + 1]
    if (-y >= height1 && -y < height2) {
      this.currentIndex = i
    }
  }
})

當點擊索引時,使用scrollToElement()方法滾動到該索引區(qū)域。

scrollTo(index) {
  this.$refs.indexList.scrollToElement(this.$refs.listGroup[index], 0)
}

具體效果可見索引列表 - 示例。

開屏引導

開屏引導,其實就是一種不自動循環(huán)播放的橫向滾動輪播圖而已。

options = {
  scrollX: true,
  snap: {
    loop: false
  }
}

this.slide = BScroll(this.$refs.slide, options)

具體效果可見開屏引導 - 示例。因為此需求場景一般只有移動端才有,所以最好在手機模式下看效果。

自由滾動

freeScroll選項,用于開啟自由滾動,允許橫向和縱向同時滾動,而不限制在某個方向。

options.freeScroll = true

另外需要注意的是,此選項在 eventPassthrough 設置了保持原生滾動時無效。

感謝各位的閱讀!關于“移動端滾動插件BetterScroll怎么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI