便利なモバイルスクロールプラグイン 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 データをインポートする方法

推薦する

MySQLトランザクションが効率に与える影響の分析と概要

1. データベース トランザクションによりデータベースのパフォーマンスが低下します。データの一貫性と...

MySQLからHiveにさらにデータをインポートするためのソリューション

元の派生コマンド: bin/sqoop インポート -connect jdbc:mysql://19...

JavaScript ベースのパスワード ボックス検証情報の実装

この記事では、パスワードボックスの検証情報を実装するためのJavaScriptの具体的なコードを例と...

Linux オペレーティング システムに Apache サービスをインストールする方法

ダウンロードリンク:動作環境VMware 仮想マシンの CentOS 7.6セキュアCRT Xftp...

MySQL OOM (メモリオーバーフロー) の解決策

OOM は「Out Of Memory」の略で、メモリオーバーフローを意味します。メモリ オーバーフ...

MySQL クエリ キャッシュとバッファ プール

1. キャッシュ - クエリキャッシュ次の図は、MySQL 公式サイトから提供されています: MyS...

LinuxでVIMエディタを使う方法

豊富なオプションを備えた強力なエディターとして、Vim は多くのユーザーに愛されています。この記事で...

NginxはIP経由の直接アクセスを禁止し、カスタム500ページにリダイレクトします

設定ファイルに直接 サーバー{ listen 80 default; # IPへの直接アクセスを禁止...

HTML はテキストの外側に省略記号を表示します...テキストオーバーフローによって実装されます

div または span に同時に CSS を適用する必要があります。コードをコピーコードは次のとお...

Vue でのルータービューコンポーネントの使用に関する詳細な説明

Vue プロジェクトを開発する場合、さまざまなコンポーネント ページを表示するために切り替えることが...

Alibaba CloudにMySQLをインストールする方法の詳細な説明

軽量のオープンソース データベースである MySQL は、エンタープライズ レベルのアプリケーション...

新しいカーネルをLinuxシステムに移植する手順

1. ubuntu16.04 イメージと対応する ubuntu16.04 カーネル バージョンのソー...

タブバーの切り替え効果を実現するJavaScript

タブバー: 異なるタブをクリックすると異なるコンテンツが表示され、クリックしたタブのスタイルが変更さ...

HTML テキストフォーマットの簡単な例 (詳細な説明)

1. テキストの書式設定: この例では、HTML ファイル内のテキストを書式設定する方法を示します...

MySQL の if 関数の正しい使い方の詳細な説明

今日私が書こうとしている内容では、プログラムは 7 時間近く実行され、データベースに 1,000 万...