BetterScroll は、モバイル端末上のさまざまなスクロール シナリオのニーズを解決することに焦点を当てたオープンソース プラグイン (GitHub アドレス) であり、スクロール リスト、セレクター、カルーセル、インデックス リスト、画面開始ガイダンスなどのアプリケーション シナリオに適しています。 。これらのシナリオを満たすために、スクロールをよりスムーズにする慣性スクロール、境界リバウンド、スクロール バーのフェードインとフェードアウトなどの柔軟な構成をサポートするだけでなく、多くの API メソッドとイベントも提供します。プルダウンによる更新やプルアップによるロードなど、スクロール シナリオの要件をより高速に実現します。
ネイティブ JavaScript に基づいて実装されており、フレームワークに依存しないため、ネイティブ JavaScript で参照したり、現在のフロントエンド MVVM フレームワークと組み合わせたりすることができます。たとえば、公式 Web サイトのサンプルは 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) ... }
エッジリバウンド
エッジを超えたときのリバウンドには 2 つの処理ステップがあります。最初のステップは境界を越えてスクロールするときに速度を低下させ、2 番目のステップは境界までリバウンドします。このうち、最初のステップは、ソース コード内の 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 } }
2 番目のステップは、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 '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 中,保证列表渲染完成时,初始化 BScroll mounted() { setTimeout(() => { this.scroll = new BScroll(this.$refs.wrapper, options) }, 20) },
初期化後、このラッパー コンテナーは正常にスクロールでき、それによって提供される API メソッドとイベントは BScroll インスタンス this.scroll を通じて使用できます。
以下では、一般的に使用されるいくつかのオプション、メソッド、イベントを紹介します。
スクロールバー
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 に設定すると、プルアップ読み込みを有効にし、読み込み開始のタイミングを決定するために下からの距離のしきい値 (しきい値) を設定できます
this.scroll.on('pullingDown', () => { // 刷新数据的过程中,回弹停留在距离顶部还有20px的位置 RefreshData() .then((newData) => { this.data = newData // 在刷新数据完成之后,调用 finishPullDown 方法,回弹到顶部 this.scroll.finishPullDown() }) })
pullUp イベントをリッスンして新しいデータを読み込みます。
options.pullUpLoad = { threshold: -20 // 在上拉到超过底部 20px 时,触发 pullingUp 事件 } this.scroll = new BScroll(this.$refs.wrapper, options)
具体的な効果は、通常のスクロールリストの例で見ることができます。
Selector
ホイール オプションは、セレクターを有効にして設定するために使用されます。セレクターの現在選択されているインデックス (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实现上拉、下拉加载刷新实例分享
以上がモバイルスクロールシナリオでの BetterScroll の適用の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。