便利なモバイルスクロールプラグイン BetterScroll

便利なモバイルスクロールプラグイン BetterScroll

著者: 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.hasHorizo​​ntalScroll とします。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 をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vueに画像がある場合にbetterScrollがプルできない問題を解決する
  • モバイルスクロールシナリオにおける BetterScroll アプリケーション

<<:  コネクタコンポーネントから Tomcat のスレッドモデルを見る - BIO モード (推奨)

>>:  MySQL 4 データをインポートする方法

推薦する

行の高さと垂直方向の配置に関する包括的な理解

前の単語line-height、font-size、vertical-align は、インライン要素...

Nodejs で WeChat アカウント分割を実装するためのサンプルコード

会社のビジネスシナリオでは、WeChat アカウント分割機能を使用する必要があります。公式 Web ...

MySQL binlog を開く手順

Binlog は、MySQL データの変更を記録するために使用されるバイナリ ログ ファイルです。B...

DockerにRedisをインストールし、パスワードを設定して接続する方法

Redis は分散キャッシュ サービスです。キャッシュは、大規模システムの開発やパフォーマンスの最適...

MySQL フルテキスト検索の中国語ソリューションとサンプルコード

MySQL 全文検索中国語ソリューション最近、会社のプロジェクトで、データベースで中国語を検索する機...

MySQL インデックスの詳細な説明

目次1. インデックスの基本1.1 はじめに1.2 インデックスの仕組み1.3 インデックスの種類1...

HTML の基本概要推奨事項 (段落)

HTML段落段落は <p> タグによって定義されます。例<p>これは段落で...

HTML チュートリアル: よく使われる HTML タグのコレクション (6)

導入された HTML タグは、必ずしも XHTML 仕様に完全に準拠しているわけではありません。実際...

MySQL 8.0.12 のインストールと使用方法のチュートリアル

MySQL 8.0.12のインストールと使用のチュートリアルを録画しました。ウィンドウズまず、公式ウ...

MySQLのスロークエリの詳細な説明

MySQL操作情報のクエリ show status -- すべての MySQL 操作情報を表示します...

CSS ファンタスティックボーダーアニメーション効果の実装

今日、私はブログサイト shoptalkshow を閲覧していて、非常に興味深いこのインターフェース...

VMware15 centos7 ブリッジモード ssh に突然アクセスできなくなる問題を解決する

仮想マシンに独自の LAN IP を持たせたいので、テストを容易にするためにブリッジを使用します。 ...

HTML/XHTML における img 画像タグの基本的な使用法の詳細な説明

画像タグは、Web ページに画像を表示するために使用されます。 HTML/XHTML 画像 <...

MySQL を暗号化および復号化するいくつかの方法 (要約)

目次前面に書かれた双方向暗号化エンコード/デコードAES_ENCRYPT/AES_DECRYPT D...