千家信息网

移动端滚动插件BetterScroll怎么用

发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,这篇文章给大家分享的是有关移动端滚动插件BetterScroll怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。让滚动更流畅在移动端,如果你使用过 overflow:
千家信息网最后更新 2024年11月19日移动端滚动插件BetterScroll怎么用

这篇文章给大家分享的是有关移动端滚动插件BetterScroll怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

让滚动更流畅

在移动端,如果你使用过 overflow: scroll 生成一个滚动容器,会发现它的滚动是比较卡顿,呆滞的。为什么会出现这种情况呢?

因为我们早已习惯了目前的主流操作系统和浏览器视窗的滚动体验,比如滚动到边缘会有回弹,手指停止滑动以后还会按惯性继续滚动一会,手指快速滑动时页面也会快速滚动。而这种原生滚动容器却没有,就会让人感到卡顿。

BetterScroll 的滚动体验

试一试 BetterScroll 的滚动体验吧。体验地址

可以发现,在增加惯性滚动,边缘回弹等效果之后,明显流畅、舒服了很多。那么,这些效果是怎么实现的呢?

惯性滚动

BetterScroll 在用户滑动操作结束时,还会继续惯性滚动一段。首先看一下源码中的 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 boundariesif (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 在各种场景下的姿势。

普通滚动列表

比如,有如下列表:

  • {{item}}

我们想要让它垂直滚动,只需要对该容器进行简单的初始化。

import BScroll from 'better-scroll'const options = {  scrollY: true // 因为scrollY默认为true,其实可以省略} this.scroll = new BScroll(this.$refs.wrapper, options)

对于 Vue 中使用 BetterScroll,有一个需要注意的点是,因为在 Vue 模板中列表渲染还没完成时,是没有生成列表 DOM 元素的,所以需要在确保列表渲染完成以后,才能创建 BScroll 实例,因此在 Vue 中,初始化 BScroll 的最佳时机是 mouted 的 nextTick。

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

初始化之后,这个 wrapper 容器就能够优雅地滚动了,并且可以通过 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 时,触发 pullingDown 事件  stop: 20 // 刷新数据的过程中,回弹停留在距离顶部还有 20px 的位置}this.scroll = new BScroll(this.$refs.wrapper, options)

监听 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 时,触发 pullingUp 事件}this.scroll = new BScroll(this.$refs.wrapper, options)

监听 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)

具体效果可见选择器 - 示例。

其中联动选择器,需要监听每个选择列表的选择,来改变其他选择列表。

data() {   return {     tempIndex: [0, 0, 0]   }},...// 监听每个选择列表的选择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选项,用于开启并配置轮播图。可配置轮播图是否循环播放(loop),每页的宽度(stepX)和高度(stepY),切换阈值(threshold),以及切换速度(speed)。

options = {  scrollX: true,  snap: {    loop: true, // 开启循环播放    stepX: 200, // 每页宽度为 200px    stepY: 100, // 每页高度为 100px    threshold: 0.3, // 滚动距离超过宽度/高度的 30% 时切换图片    speed: 400 // 切换动画时长 400ms  }}this.slide = BScroll(this.$refs.slide, options)

具体效果可见轮播图 - 示例。

特殊场景

除了普通滚动列表、选择器、轮播图等基础滚动场景,还可以利用 BetterScroll 提供的能力,做一些特殊场景。

索引列表

索引列表,首先需要在滚动过程中实时监听滚动到哪个索引的区域了,来更新当前索引。在这种场景下,我们可以使用probeType选项,当此选项设置为 3 时,会在整个滚动过程中实时派发 scroll 事件。从而获取滚动过程中的位置。

options.probeType = 3this.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()方法滚动到该索引区域。

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

具体效果可见索引列表 - 示例。

开屏引导

开屏引导,其实就是一种不自动循环播放的横向滚动轮播图而已。

options = {  scrollX: true,  snap: {    loop: false  }}this.slide = BScroll(this.$refs.slide, options)

具体效果可见开屏引导 - 示例。因为此需求场景一般只有移动端才有,所以最好在手机模式下看效果。

自由滚动

freeScroll选项,用于开启自由滚动,允许横向和纵向同时滚动,而不限制在某个方向。

options.freeScroll = true

另外需要注意的是,此选项在 eventPassthrough 设置了保持原生滚动时无效。

感谢各位的阅读!关于"移动端滚动插件BetterScroll怎么用"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

0