著者: Didi Web アプリ アーキテクチャ チーム - Fu Nan BetterScroll は、モバイル デバイス上のさまざまなスクロール シナリオ要件の解決に重点を置いたオープン ソース プラグイン (GitHub アドレス) です。スクロール リスト、セレクター、カルーセル、インデックス リスト、オープニング スクリーン ガイドなどのアプリケーション シナリオに適しています。 これらのシナリオに対応するために、慣性スクロール、境界リバウンド、スクロールバーのフェードインとフェードアウト効果の柔軟な構成をサポートし、スクロールをよりスムーズにするだけでなく、プルダウンリフレッシュやプルアップロードなど、スクロールシナリオのニーズをより迅速に実現できるように、多くの API メソッドとイベントも提供しています。 ネイティブ JavaScript ベースで実装されており、フレームワークに依存しないため、ネイティブ JavaScript で参照したり、現在のフロントエンド MVVM フレームワークと組み合わせて使用したりできます。たとえば、公式サイトの例では Vue と組み合わせています。 まず、スクロールがスムーズになる仕組みを見てみましょう。 スクロールをスムーズにするモバイル デバイスでは、overflow: scroll を使用してスクロール コンテナーを生成すると、スクロールがかなりぎくしゃくして遅くなることがわかります。なぜこのようなことが起こるのでしょうか? 現在主流のオペレーティングシステムやブラウザウィンドウのスクロール体験に私たちは長い間慣れているからです。たとえば、端までスクロールするとリバウンドが発生し、指はスライドを止めた後も慣性によってしばらくスクロールし続けます。指を素早くスライドすると、ページも素早くスクロールします。このネイティブスクロールコンテナーにはそれがないため、ユーザーは行き詰まったように感じます。 BetterScrollのスクロール体験BetterScrollをお試しください。体験住所 慣性スクロール、エッジリバウンドなどの効果を追加した後は、明らかにスムーズで快適になっていることがわかります。では、これらの効果はどのようにして達成されるのでしょうか? 慣性ローリングユーザーがスライド操作を終了しても、BetterScroll はしばらくスクロールを続けます。まず、ソースコード内の BScroll.prototype._end 関数を見てみましょう。これは、touchend、mouseup、touchcancel、mousecancel イベントの処理関数で、ユーザーのスクロール操作が終了したときのロジックです。 BScroll.prototype._end = 関数 (e) { ... if (this.options.momentum && 期間 < this.options.momentumLimitTime && (absDistY > this.options.momentumLimitDistance || absDistX > this.options.momentumLimitDistance)) { momentumX = this.hasHorizontalScroll とします。momentum(this.x、this.startX、duration、this.maxScrollX、this.options.bounce ? this.wrapperWidth : 0、this.options) : {宛先: newX、期間: 0} momentumY = this.hasVerticalScroll とします。momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options) : {宛先: newY、期間: 0} newX = 勢いX.目的地 新しいY = 勢いY.目的地 時間 = Math.max(momentumX.duration, momentumY.duration) this.isInTransition = 1 } ... } 上記のコードの目的は、慣性スクロールをオンにする必要がある場合に、momentum 関数を使用して、ユーザーのスライド操作が終了したときの慣性スクロールの距離と時間を計算することです。この機能は、ユーザーのスライド速度と減速オプション(慣性減速)に基づいてスクロール距離を計算します。スクロール時間についても、設定可能なオプションです。 関数 momentum(現在, 開始, 時間, 下限マージン, wrapperSize, オプション) { ... 距離 = 現在値 - 開始値 速度 = Math.abs(距離) / 時間 ... 継続時間をswipeTimeとします 目的地 = 現在の速度 + 減速度 * (距離 < 0 ? -1 : 1) とします。 ... } エッジリバウンド境界を超えたときのリバウンドには 2 つの処理ステップがあります。1 つ目のステップは、境界を超えてスクロールするときに速度を遅くすること、2 つ目のステップは境界までリバウンドすることです。最初のステップは、ソース コード内の BScroll.prototype._move 関数にあります。これは、touchmove イベントと mousemove イベントの処理関数、つまり、ユーザーのスライド操作中のロジックです。 // 境界外の場合は減速または停止する (newY > 0 || newY < this.maxScrollY) の場合 { if (this.options.bounce) { 新しいY = this.y + デルタY / 3 } それ以外 { newY = newY > 0 ? 0 : this.maxScrollY } } 2 番目のステップは、BScroll.prototype.resetPosition 関数を呼び出して境界に戻ることです。 BScroll.prototype.resetPosition = 関数 (time = 0, easing = easy.bounce) { ... y = this.y とします。 if (!this.hasVerticalScroll || y > 0) { y = 0 } そうでない場合 (y < this.maxScrollY) { y = this.maxScrollY } ... this.scrollTo(x, y, 時間, イージング) ... } スムーズなスクロールは単なる基礎にすぎません。BetterScoll の真の力は、さまざまなスクロール要件をより効率的にするための、多数の一般/カスタマイズ オプション、API メソッド、イベントを提供することにあります。 さまざまな需要シナリオへの適用方法次に、Vue の使用を例に、さまざまなシナリオでの BetterScroll について説明します。 通常のスクロールリストたとえば、次のリストがあります。 <div ref="ラッパー" class="リストラッパー"> <ul class="list-content"> <li @click="clickItem($event,item)" class="list-item" v-for="item in data">{{item}}</li> </ul> </div> 垂直方向にスクロールさせたいので、コンテナの簡単な初期化を実行するだけです。 'better-scroll' から BScroll をインポートします 定数オプション = { scrollY: true // scrollY はデフォルトで true なので省略できます} this.scroll = 新しい BScroll(this.$refs.wrapper, オプション) Vue で BetterScroll を使用する場合、注意すべき点が 1 つあります。Vue テンプレートではリストのレンダリングが完了していないとリストの DOM 要素が生成されないため、リストのレンダリングが完了したことを確認してからでないと BScroll インスタンスを作成できません。そのため、Vue では BScroll を初期化する最適なタイミングは mouted の nextTick です。 // Vue では、リストのレンダリングが完了したら BScroll が初期化されることを確認します マウント() { タイムアウトを設定する(() => { this.scroll = 新しい BScroll(this.$refs.wrapper, オプション) }, 20) }, 初期化後、ラッパー コンテナーは正常にスクロールできるようになり、BScroll インスタンス this.scroll によって提供される API メソッドとイベントを使用できるようになります。 以下は、よく使用されるオプション、メソッド、およびイベントの一部です。 スクロールバーscrollbar オプションは、スクロール バーを構成するために使用されます。デフォルト値は false です。 true またはオブジェクトに設定すると、スクロール バーが有効になります。また、フェード プロパティを使用して、スクロール時にスクロール バーをフェードインおよびフェードアウトさせるか、または表示したままにするかを設定することもできます。 // フェードのデフォルトは true、スクロールバーはフェードインおよびフェードアウトします。options.scrollbar = true // スクロールバーは常に表示されます options.scrollbar = { フェード: 偽 } this.scroll = 新しい BScroll(this.$refs.wrapper, オプション) 具体的な効果については、「通常のスクロール リスト - 例」を参照してください。 下に引いて更新pullDownRefresh オプションは、プルダウン更新機能を構成するために使用されます。 trueまたはオブジェクトに設定すると、プルダウン更新が有効になります。更新タイミングを決定するプルダウン距離(しきい値)とリバウンド停止距離(停止)を設定できます。 オプション.pullDownRefresh = { threshold: 50, // プルダウンが上から 50px を超えると、pullingDown イベントがトリガーされます stop: 20 // データ更新プロセス中、リバウンドは上から 20px 離れた位置に留まります} this.scroll = 新しい BScroll(this.$refs.wrapper, オプション) pullingDown イベントをリッスンし、データを更新します。データを更新した後、finishPullDown() メソッドを呼び出して上部の境界に戻ります。 this.scroll.on('pullingDown', () => { // データ更新プロセス中、リバウンドは上部から 20 ピクセル離れたままです RefreshData() .then((新しいデータ) => { this.data = 新しいデータ // データを更新した後、finishPullDown メソッドを呼び出して先頭に戻ります this.scroll.finishPullDown() }) }) 具体的な効果については、「通常のスクロール リスト - 例」を参照してください。 プルアップローディングpullUpLoad オプションは、プルアップ ロード機能を構成するために使用されます。 true またはオブジェクトに設定すると、プルアップ読み込みを有効にでき、下部からの距離しきい値を構成して、読み込みを開始するタイミングを決定できます。 オプション.pullUpLoad = { しきい値: -20 // プルアップが下から 20px を超えると、pullingUp イベントがトリガーされます} this.scroll = 新しい BScroll(this.$refs.wrapper, オプション) pullingUp イベントをリッスンし、新しいデータを読み込みます。 this.scroll.on('pullingUp', () => { ロードデータ() .then((新しいデータ) => { this.data.push(新しいデータ) }) }) 具体的な効果については、「通常のスクロール リスト - 例」を参照してください。 セレクタホイール オプションは、セレクターを有効にして構成するために使用されます。セレクターの現在選択されているインデックス (selectedIndex)、リストの曲率 (rotate)、および選択された項目を切り替えるための調整時間 (adjustTime) を設定できます。 オプション.ホイール = { 選択されたインデックス: 0, 回転: 25, 調整時間: 400 } // セレクターの各列を初期化します this.wheels[i] = new BScroll(wheelWrapper.children[i], options) 詳細については、「セレクター - 例」を参照してください。 リンケージ セレクターは、他の選択リストを変更するために、各選択リストの選択を監視する必要があります。 データ() { 戻る { 一時インデックス: [0, 0, 0] } }, ... // 各選択リストの選択をリッスンします this.wheels[i].on('scrollEnd', () => { this.tempIndex.splice(i, 1, this.wheels[i].getSelectedIndex()) }) ... // 現在の選択に基づいて他の選択リストの内容を決定します: { リンクデータ() { const 州 = 州リスト const 都市 = 都市リスト[州[this.tempIndex[0]].値] 定数エリア = areaList[都市[this.tempIndex[1]].値] [州、都市、地域]を返す } }, 詳細については、「セレクター - 例のリンクされたセレクター」を参照してください。 カルーセルスナップ オプションは、カルーセルを有効にして構成するために使用されます。スライドショーをループ再生するかどうか (loop)、各ページの幅 (stepX) と高さ (stepY)、切り替えしきい値 (threshold)、切り替え速度 (speed) を設定できます。 オプション = { スクロールX: true、 スナップ: { loop: true, // ループ再生を開始 stepX: 200, // 各ページの幅は 200 ピクセルです stepY: 100, // 各ページの高さは100pxです threshold: 0.3, // スクロール距離が幅/高さの 30% を超えると画像を切り替える speed: 400 // 切り替えアニメーションの持続時間 400ms } } this.slide = BScroll(this.$refs.slide, オプション) 具体的な効果については、「スライドショー - 例」を参照してください。 特別なシナリオ通常のスクロール リスト、セレクター、カルーセルなどの基本的なスクロール シナリオに加えて、BetterScroll が提供する機能を使用して特別なシナリオを実行することもできます。 インデックスリストインデックス リストは、まず、スクロール プロセス中にどのインデックス領域までスクロールされたかをリアルタイムで監視し、現在のインデックスを更新する必要があります。このシナリオでは、probeType オプションを使用できます。このオプションを 3 に設定すると、スクロール プロセス全体にわたってスクロール イベントがリアルタイムで送信されます。これにより、スクロール処理中の位置が取得されます。 オプション.プローブタイプ = 3 this.scroll = 新しい BScroll(this.$refs.wrapper, オプション) this.scroll.on('スクロール', (pos) => { 定数 y = pos.y (i = 0 とします; i < listHeight.length - 1; i++) { height1 = listHeight[i]とする height2 = listHeight[i + 1]とします。 (-y >= 高さ1 && -y < 高さ2) の場合 { this.currentIndex = i } } }) インデックスをクリックすると、scrollToElement() メソッドを使用してそのインデックス領域までスクロールします。 scrollTo(インデックス) { this.$refs.indexList.scrollToElement(this.$refs.listGroup[index], 0) } 詳細については、「インデックス リスト - 例」を参照してください。 画面ガイドを開くオープニング画面のガイドは、実際には自動的にループしない、水平にスクロールするカルーセルです。 オプション = { スクロールX: true、 スナップ: { ループ: false } } this.slide = BScroll(this.$refs.slide, オプション) 具体的な効果については、オープニング画面ガイド - 例を参照してください。この需要シナリオは通常モバイル デバイスでのみ利用できるため、モバイル モードで効果を確認するのが最適です。 無料スクロールfreeScroll オプションは、フリースクロールを有効にするために使用され、特定の方向に制限されることなく、水平スクロールと垂直スクロールの両方が可能になります。 options.freeScroll = true また、eventPassthrough がネイティブ スクロールを維持するように設定されている場合、このオプションは効果がないことに注意してください。 具体的な効果については、「フリースクロール - 例」を参照してください。 まとめBetterScroll は、ほぼすべてのスクロール シナリオで使用できます。この記事では、いくつかの典型的なシナリオでの使用法についてのみ紹介します。 BetterScroll は、モバイル デバイスのスクロール ニーズを解決するために設計されたプラグインとして、多くのオプション、メソッド、イベントを提供し、スクロールをより迅速、柔軟、正確に処理する機能を提供します。 これで、BetterScroll という便利なモバイル スクロール プラグインに関するこの記事は終わりです。BetterScroll モバイル スクロール プラグインに関するその他の関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: コネクタコンポーネントから Tomcat のスレッドモデルを見る - BIO モード (推奨)
目次1: galera-clusterの紹介2. galera-clusterの仕組み3: Mari...
ページ上の画像を強調表示することは非常に一般的です。ここでは、jQuery を使用して画像を強調表示...
データのバックアップと復元パート3の詳細は次のとおりです基本的な概念:バックアップ、現在のデータまた...
ルーティングvue-router4 では API の大部分は変更されていないため、変更点のみに焦点を...
ボタン (input, button) を記述すると、IE では次のようになります。単語数が増えると...
WeChat 8.0 アップデートの主な特徴は、アニメーション絵文字のサポートです。送信するメッセー...
目次OAuth アプリの作成コードを取得するaccess_tokenを取得するユーザー情報を取得する...
以下は、私のプロジェクトでこのプロパティを使用する方法の例です。 (1)激しく透明な浮遊コードをコピ...
nginx バージョン 1.11.3次の構成を使用すると、検証は無効になり、クロスドメインの問題が依...
仮想マシンは非常に便利なテストソフトウェアです。ハードウェアに損傷を与えることなく、さまざまなテスト...
Electronのインストール cnpm 電子をインストール -g electron-package...
この記事では、例を使用して、MySQL 外部キーの基本的な機能と使用方法を説明します。ご参考までに、...
プラットフォームの展開1. JDKをインストールするステップ1. OracleJDKをダウンロードす...
Tomcat8 イメージをダウンロード [root@localhost ~]# docker sea...
目次2. pt-pmapを使用したスタック分析3. このコラムのボトルネックポイントの分析4. パー...