>  기사  >  웹 프론트엔드  >  모바일 스크롤링 시나리오에서 BetterScroll 적용

모바일 스크롤링 시나리오에서 BetterScroll 적용

小云云
小云云원래의
2018-02-09 13:54:361608검색

BetterScroll은 모바일 측의 다양한 스크롤 시나리오 요구 사항을 해결하는 데 중점을 둔 오픈 소스 플러그인(GitHub 주소)입니다. 스크롤 목록, 선택기, 캐러셀, 인덱스 목록 및 화면 열기 안내와 같은 애플리케이션 시나리오에 적합합니다. . 이러한 시나리오를 충족하기 위해 관성 스크롤링, 경계 리바운드, 스크롤 막대 페이드인 및 페이드아웃 효과 등의 유연한 구성을 지원하여 스크롤을 더욱 원활하게 할 뿐만 아니라 다양한 API 메서드와 이벤트를 제공하여 우리가 새로고침을 위한 풀다운 및 로드를 위한 풀업과 같은 요구 사항을 스크롤링 시나리오에서 더 빠르게 실현할 수 있습니다.

네이티브 JavaScript를 기반으로 구현되어 어떠한 프레임워크에도 의존하지 않기 때문에 네이티브 JavaScript에서 참조하거나 현재 프런트엔드 MVVM 프레임워크와 결합할 수 있습니다. 예를 들어 공식 웹사이트의 예제는 Vue와 결합됩니다.

먼저 스크롤이 어떻게 더 부드러워지는지 살펴보겠습니다.

스크롤을 더 부드럽게 만들기

모바일 측에서 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
  }
  ...
}

위 코드의 기능은 사용자의 슬라이딩 작업이 끝날 때 관성 스크롤을 켜야 하는 경우 운동량 함수를 사용하여 관성 스크롤 거리와 시간을 계산하는 것입니다. 이 기능은 사용자의 슬라이딩 조작 속도와 감속 옵션(관성 감속도)을 기준으로 스크롤 거리를 계산하는 기능으로, 스크롤 시간도 구성 가능한 옵션입니다.

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)
 ...
}

Edgebound

Edge를 초과할 때의 Rebound에는 두 가지 처리 단계가 있습니다. 첫 번째 단계는 경계를 넘어 스크롤할 때 속도를 늦추는 것이고, 두 번째 단계는 경계로 되돌아가는 것입니다. 그 중 첫 번째 단계는 소스코드의 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의 진정한 능력은 다양한 스크롤 요구 사항을 보다 효율적으로 만들기 위한 수많은 일반/맞춤형 옵션, API 방법 및 이벤트를 제공하는 데 있습니다.

다양한 수요 시나리오에 적용하는 방법

이제 Vue의 활용을 예로 들어 다양한 시나리오에서의 BetterScroll의 자세에 대해 이야기해 보겠습니다.

일반 스크롤 목록

예를 들어 다음 목록이 있습니다.

{{item}}

우리는 수직으로 스크롤하도록 만들고 싶고, 컨테이너의 간단한 초기화만 수행하면 됩니다.

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

Vue에서 BetterScroll을 사용할 때 주의할 점은 Vue 템플릿에서 목록 렌더링이 완료되기 전에 목록 DOM 요소가 생성되지 않기 때문에 BScroll 인스턴스를 생성하기 전에 목록 렌더링이 완료되었는지 확인해야 한다는 것입니다. 따라서 Vue에서 BScroll을 초기화하는 가장 좋은 시간은 moouts의 nextTick입니다.

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

초기화 후 이 래퍼 컨테이너는 정상적으로 스크롤할 수 있으며, 이 컨테이너에서 제공하는 API 메서드와 이벤트는 BScroll 인스턴스 this.scroll을 통해 사용할 수 있습니다.

다음은 일반적으로 사용되는 몇 가지 옵션, 방법 및 이벤트를 소개합니다.

Scroll bar

scrollbar 옵션, 스크롤 막대를 구성하는 데 사용되며 기본값은 false입니다. true 또는 객체로 설정하면 스크롤 막대가 활성화됩니다. 또한 페이드 속성을 사용하여 스크롤 작업으로 스크롤 막대가 페이드 인 및 페이드 아웃되는지 아니면 표시된 상태로 유지되는지 구성할 수 있습니다.

// fade 默认为 true,滚动条淡入淡出
options.scrollbar = true
// 滚动条一直显示
options.scrollbar = {
 fade: false
}
this.scroll = new BScroll(this.$refs.wrapper, options)

일반적인 스크롤 목록 예시에서 구체적인 효과를 확인할 수 있습니다.

풀다운 새로고침

pullDownRefresh 옵션은 풀다운 새로고침 기능을 구성하는 데 사용됩니다. true 또는 객체로 설정하면 상단 풀다운 거리(임계값)를 구성하여 새로 고침 타이밍과 리바운드 유지 거리(중지)를 결정할 수 있습니다. 데이터를 새로 고칩니다. 그리고 데이터를 새로 고친 후 FinishPullDown() 메서드를 호출하여 위쪽 테두리로 다시 이동합니다

options.pullDownRefresh = {
 threshold: 50, // 当下拉到超过顶部 50px 时,触发 pullingDown 事件
 stop: 20 // 刷新数据的过程中,回弹停留在距离顶部还有 20px 的位置
}
this.scroll = new BScroll(this.$refs.wrapper, options)

구체적인 효과는 일반적인 스크롤 목록 예제에서 볼 수 있습니다.

PullUpLoad

pullUpLoad 옵션은 풀업 로딩 기능을 구성하는 데 사용됩니다. true 또는 Object로 설정 시 풀업 로딩이 가능하며, 하단으로부터의 거리 임계값(threshold)을 설정하여 로딩 시작 시점을 결정할 수 있습니다

this.scroll.on('pullingDown', () => {
 // 刷新数据的过程中,回弹停留在距离顶部还有20px的位置
 RefreshData()
  .then((newData) => {
   this.data = newData
   // 在刷新数据完成之后,调用 finishPullDown 方法,回弹到顶部
   this.scroll.finishPullDown()
 })
})

pullingUp 이벤트를 듣고 새로운 데이터를 로딩할 수 있습니다.

options.pullUpLoad = {
 threshold: -20 // 在上拉到超过底部 20px 时,触发 pullingUp 事件
}
this.scroll = new BScroll(this.$refs.wrapper, options)

특정 효과는 일반적인 스크롤 목록 예시에서 확인할 수 있습니다.

Selector

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

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 可以用于几乎所有滚动场景,本文仅介绍了在一些典型场景下的使用姿势。

作为一款旨在解决移动端滚动需求的插件,BetterScroll 开放的众多选项、方法和事件,其实,就是提供了一种让我们更加快捷、灵活、精准时机地处理滚动的能力。

相关推荐:

微信小程序YDUI的ScrollTab组件滚动选项卡效果详解

jquery使用iscroll实现上拉、下拉加载刷新实例分享

vue滚动轴插件better-scroll详解

위 내용은 모바일 스크롤링 시나리오에서 BetterScroll 적용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.