Scrollend(新しい JavaScript イベント)

タイムアウト関数を削除し、バグを取り除きます。本当に必要なイベントである Scrollend があります。

Adam Argyle 氏
Adam Argyle

scrollend イベント以前は、スクロールの完了を検出する信頼できる方法がありませんでした。これは、ユーザーが指を画面に置いたままでも、遅れてイベントが発生することを意味します。この信頼性が低いため、スクロールが実際に終了したタイミングがわからないため、バグやユーザー エクスペリエンスの低下につながりました。

変更前
document.onscroll = event => {
  clearTimeout(window.scrollEndTimer)
  window.scrollEndTimer = setTimeout(callback, 100)
}

この setTimeout() 戦略で可能なことは、100ms のスクロールが停止したかどうかを把握することです。これにより、スクロールの終了イベントではなく、スクロールの一時停止イベントのように動作します。

scrollend イベントの後、ブラウザはこのような難しい評価をすべて行います。

変更後
document.onscrollend = event => {…}

それがいいわね。出力前に意味のある条件を揃えてタイミングをとれ 値を表示する必要があります

対応ブラウザ

  • 114
  • 114
  • 109
  • x

ソース

試してみる

イベントの詳細

scrollend イベントは以下の場合に発生します。 - ブラウザがスクロールのアニメーション化または翻訳を停止した。 - ユーザーのタップが離されました。 - ユーザーのポインタがスクロールのつまみを離した。 - ユーザーのキー操作が解放されました。 - フラグメントへのスクロールが完了しました。 - スクロールのスナップが完了しました。 - scrollTo() が完了しました。 - ユーザーがビジュアル ビューポートをスクロールしました。

次の場合、scrollend イベントは起動しません。 - ユーザーの操作によってスクロール位置が変化しなかった(移動が発生しなかった)。 - scrollTo() は翻訳できませんでした。

仕様の詳細が必要な詳細情報が多く、このイベントがウェブ プラットフォームに到達するまでにこれほど時間がかかる理由がありました。特に複雑な領域として、ドキュメントではなくビジュアル ビューポートscrollend の詳細を明確に示すことでした。ウェブページを拡大表示した場合について考えてみましょう。このズーム状態ではスクロールできます。ドキュメントをスクロールするとは限らないこのような視覚的ビューポートのユーザー ドリブンなスクロール操作であっても、完了すると scrollend イベントが出力されます。

イベントの使用

他のスクロール イベントと同様に、リスナーはいくつかの方法で登録できます。

addEventListener("scrollend", (event) => {
  // scroll ended
});

aScrollingElement.addEventListener("scrollend", (event) => {
  // scroll ended
});

または、次のようにイベント プロパティを使用します。

document.onscrollend = (event) => {
  // scroll ended
};

aScrollingElement.onscrollend = (event) => {
  // scroll ended
};

ポリフィルと段階的な補正

この新しいイベントを今すぐ使用したい方には、次のアドバイスがおすすめです。現在のスクロール終了戦略(使用している場合)を引き続き使用し、最初に以下を使用してサポート状況を確認します。

'onscrollend' in window
// true, if available

ブラウザがイベントを提供しているかどうかによって、true または false がレポートされます。このチェックにより、コードを分岐できます。

if ('onscrollend' in window) {
  document.onscrollend = callback
}
else {
  document.onscroll = event => {
    clearTimeout(window.scrollEndTimer)
    window.scrollEndTimer = setTimeout(callback, 100)
  }
}

これは、scrollend イベントが利用可能な場合に徐々に強化される正常動作です。また、次に示すように、ブラウザの機能を最大限に活かすために作成したpolyfillNPM)も試してみてください。

import {scrollend} from "scrollyfills"

// then use scrollend as if it's existed this whole time
document.onscrollend = callback

ポリフィルは段階的に拡張され、ブラウザの組み込み scrollend イベント(使用可能な場合)を使用できるようになります。イベントがない場合、スクリプトはポインタ イベントを監視し、スクロールすることで、イベントの終了を最適に推定します。

ユースケース

スクロールの実行中に計算量の多い作業が発生しないようにすることをおすすめします。これにより、スクロールができるだけ多くのメモリと処理を自由に使用して、エクスペリエンスをスムーズに保つことができます。scrollend イベントを使用するとスクロールが発生しなくなるため、呼び出しを行い、ハードな作業を行うのに最適なタイミングです。

scrollend イベントを使用して、さまざまなアクションをトリガーできます。一般的なユースケースは、関連する UI 要素をスクロールを停止した位置と同期することです。例: - カルーセルのスクロール位置をドット インジケーターと同期させる。 - ギャラリー アイテムとそのメタデータの同期。 - ユーザーが新しいタブにスクロールした後にデータを取得する。

ユーザーがメールをスワイプする状況について考えてみましょう。スワイプが終了したら、スクロールした場所に基づいてアクションを実行できます。

このイベントは、プログラムやユーザー スクロール後の同期や、ロギング分析などのアクションにも使用できます。

スクロール位置に基づいて矢印、ドット、フォーカスなどの複数の要素を更新する必要がある好例を以下に示します。このカルーセルの作成方法については、YouTube をご覧ください。また、ライブデモをお試しください。

エンジニアリング作業の Mehdi Kazemi、API と実装ガイダンスの Robert Flack に感謝します。