スクロール スナップ イベント

Adam Argyle
Adam Argyle

Chrome 129 以降では、JavaScript の scrollSnapChange イベントと scrollSnapChanging イベントを使用できます。組み込みのスナップ イベントを実装すると、以前は表示されなかったスナップ状態を、適切なタイミングで、常に正しく操作できるようになります。これらのイベントがないと便利ではありませんでした。

scrollSnapChange より前は、交差点オブザーバーを使用してスクロール ポートを横切る要素を見つけることができましたが、スナップされた要素の特定はいくつかの状況に限定されていました。たとえば、スナップ アイテムがスクロール ポートを埋めているか、スクロール ポートの大部分を占めているかを検出できます。そのためには、スクロール領域の交差する要素を監視し、スクロール領域の大部分を占めているアイテムに基づいて、これがスナップ ターゲットであると想定し、scrollend を待ってからスナップされたアイテム(スナップ ターゲット)を処理します。

しかし、scrollSnapChanging より前は、スナップ ターゲットがいつ変化しているのか、(スクロール フリングなどで)何が変更されたのかを知ることは不可能でした。

スナップ ターゲットとして内側に番号の付いたボックスがある水平スクローラーが表示されています。左側には、scrollSnapChange イベントのリアルタイム ログがあり、snapTargetInline が青色でハイライト表示されています。右側には、scrollSnapChanged イベントのリアルタイム ログがあり、snapTargetInline が灰色でハイライト表示されています。

試してみる
https://codepen.io/web-dot-dev/pen/jOjaaEP

これらの新しいイベントにより、これらの情報をすばやく簡単に確認できるようになりました。これにより、スクロール スナップの操作が現在の機能を超えて広がり、スクロール スナップの関係と最新の UI フィードバック シナリオのオーケストレーションが可能になります。

<ph type="x-smartling-placeholder">

scrollSnapChange

このイベントは、スクロール操作によって新しいスナップ ターゲットが以下の順序で配置された場合にのみ発生します。

  1. スクロールが止まった後。
  2. scrollend より前。

このイベントは、スクロール完了時に scrollend の直前で、新しいスナップ ターゲットがに置かれた場合にのみ発生します。これにより、スクロール操作が完了すると、イベントは遅延している、あるいはジャスト イン タイムとして表示されているように見えます。

scroller.addEventListener('scrollsnapchange', event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
})

scroller.onscrollsnapchange = event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
}

このイベントは、イベント オブジェクト上にスナップされたアイテムを snapTargetBlock および snapTargetInline として公開します。スクローラーが水平方向のみの場合、snapTargetBlock プロパティは null になります。プロパティの値は要素ノードです。

ScrollSnapChange 固有の詳細

ユーザーがジェスチャーを離すまで発動しない

画面上を指、またはトラックパッドに指がある場合、ユーザーの操作でスクロールが完了していません。これは、スクロールが終了していないことを意味します。つまり、スナップ ターゲットがまだ変更されておらず、ユーザー操作の完了を保留していることを意味します。

スナップ ターゲットが変更されていない場合は配信されません

このイベントはスナップ変更用です。スナップ ターゲットが変更されていなければ、ユーザーがスクローラーを操作してもイベントは起動しません。実際にはユーザーがスクロールしたため、スクロール完了後も scrollend イベントが発生します。

scrollSnapChanging

このイベントは、スクロール操作によって新しいスナップ ターゲットが作成されるか、または作成されるとブラウザが判断するとすぐに発生します。スクロール中に頻繁に起動されます。

scroller.addEventListener('scrollsnapchanging', event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
})

scroller.onscrollsnapchanging = event => {
  console.log(event.snapTargetBlock);
  console.log(event.snapTargetInline);
}

このイベントは、イベント オブジェクト上にスナップされたアイテムを snapTargetBlock および snapTargetInline として公開します。スクローラーが垂直方向のみの場合、snapTargetInline プロパティは null になります。プロパティの値は要素ノードです。

ScrollSnap Changes の固有の詳細

スクロール操作中に頻繁に早期に起動する

ユーザーの完全なスクロール操作を待機する scrollSnapChange とは異なり、このイベントはユーザーが指またはトラックパッドを使用してスクロールすると積極的に呼び出されます。たとえば、ユーザーが指を離さずにゆっくりとスクロールしているとすると、ユーザーが複数のスナップ ターゲットをパンしている限り、操作中に scrollSnapChanging が複数回起動されます。ユーザーがスクロールするたびに、リリース時に新しいスナップ ターゲットの上に重なるとブラウザが判断した場合、イベントが起動し、どの要素が該当するかがわかります。

新しいスナップ ターゲットに向かう途中ですべてのスナップ ターゲットが起動されない

さらに、ユーザーが一度に複数のスナップ ターゲットにまたがるスクロール スロー ジェスチャーを行うフリングについて考えてみましょう。このイベントは、基盤となるターゲットで 1 回呼び出されます。スナップ ターゲットはできるだけ早く提供できるので、負荷が高くても無駄ではありません。

ユースケースと例

これらのイベントにより、多くの新しいユースケースが実現すると同時に、現在のパターンの実装がはるかに容易になります。典型的な例は、[スナップでトリガーされるアニメーション] を有効にすることです。スナップ アイテム、スナップ アイテムの子、または関連する情報がスナップ ターゲットである場合に、コンテキストに基づいて表示されます。

次のパターンは、すぐに生産性を上げるのに役立つユースケースを示しています。

お客様の声を紹介する

この例は、スナップされたお客様の声を宣伝したり、視覚的に焦点を合わせたりしています。

scroller.onscrollsnapchange = event => {
  scroller.querySelector(':scope .snapped')?.classList.remove('snapped')
  event.snapTargetInline.classList.add('snapped')
}
<ph type="x-smartling-placeholder">
https://codepen.io/web-dot-dev/pen/dyBZZPe

スナップされたアイテムの説明を表示する

以下の例は、スナップされたアイテムの説明を示しています。このデモには両方のイベントが含まれているため、scrollSnapChangescrollSnapChanging のタイミングとユーザー エクスペリエンスの違いを確認できます。

スナップ変更
https://codepen.io/web-dot-dev/pen/wvLPPBL

スナップ変更
https://codepen.io/web-dot-dev/pen/QWXOObw

スナップされたプレゼンテーション スライドの子を一度アニメーション化する

この例では、新しいスライドが着地して元の位置に置かれたことを認識します。コンテンツを一度アニメーション化するのに最適なタイミングです。

document.addEventListener('scrollsnapchange', event => {
  event.snapTargetBlock.classList.add('seen')
})
<ph type="x-smartling-placeholder">
https://codepen.io/web-dot-dev/pen/rNEYYVj

スクローラーの x と y の両方でスナップする

スクロール スナップは、水平方向と垂直方向のスクロールが可能なスクローラーで機能します。このデモでは、グリッドをスクロールすると scrollSnapChangingscrollSnapChange の両方のターゲットが表示されます。このデモでは、ブラウザがスナップする要素が、想定したとおりの要素と異なる場合があることを説明します。

水平方向と垂直方向のスクローラーで、正方形のグリッドが表示されています。破線の枠線は scrollSnapChanged ターゲットを表し、実線の枠線は scrollSnapChange ターゲットです。赤は snapTargetInline を表し、青は snapTargetBlock を表します。

https://codepen.io/web-dot-dev/pen/qBzVVdp

2 つのリンクされたスクローラー

このデモには 2 つのスクロール スナップ コンテナがあり、1 つはリンクの概要リスト、もう 1 つは実際のページング コンテンツです。新しい scrollSnapChanging イベントを使用すると、これらのスナップ状態を簡単に双方向にリンクして、常に同期できます。

<ph type="x-smartling-placeholder">
</ph>
https://codepen.io/web-dot-dev/pen/YzoEEXj

OKLCH カラー選択ツール

このデモには 3 つのスクローラーがあり、それぞれ OKLCH で異なるカラーチャンネルを表します。スナップされたアイテムは関連するラジオグループと同期され、入力をラップしたフォームからデータを取得できます。マウスまたはタップ操作では、目的の値までスクロールします。キーボードを使用している場合は、Tab キーと矢印キーを使用します。スクリーン リーダーでは、これは単なるフォームです。

つもり

https://codepen.io/web-dot-dev/pen/OJeOOVG

躍動感あふれるアニメーション ハブ

このデモでは、scrollsnapchange を使用してスナップ トリガー遷移でスクロールのスナップ体験を段階的に強化します。

次の JavaScript でイベントのサポートを確認します。

if ('onscrollsnapchange' in window) {
  // ok to use snap change
}
<ph type="x-smartling-placeholder">
https://codepen.io/web-dot-dev/pen/MWMOOae

スクロール可能なルーラー入力

このデモでは、数値入力で長さを選択する代替方法としてスクロール可能なルーラーについて説明します。数値入力に直接値を入力するか、サイズまでスクロールします。change イベントは、ユーザーの操作中に選択をクリアするために使用され、change イベントは、状態を更新してユーザーの選択を強化するために使用されます。

<ph type="x-smartling-placeholder">
</ph>
https://codepen.io/web-dot-dev/pen/LYKOOpd

カバーフロー

このデモは、有名な macOS のカバーフローを再現した Bramus Van Damme によるスクロールドリブンの優れたアニメーションを基に作成されています(動画チュートリアルもご覧ください)。一意には、scrollSnapChanging を使用してアルバム タイトルを非表示にし、scrollSnapChange を使用してタイトルを表示します。これらのイベントにより、古いタイトルには隠れた隠れ蓑や、新しいタイトルをゆっくりと見せることができます。

<ph type="x-smartling-placeholder">
</ph>
https://codepen.io/web-dot-dev/pen/Bagmmog

創造性を刺激するその他のアイデア

どの要素がスナップされ、どの要素がアクティブにスナップされているかを簡単に判別できるようになったため、さまざまな新しい可能性があります。創造性を刺激するアイデアやその他のユースケースは次のとおりです。

  • 遅延読み込みをトリガーする(Snapchange トリガー型レンダリングまたはデータ取得)
  • 大きな画像にリンクされているフィルム ストリップのサムネイル。
  • スナップされた動画のサムネイルで、予告動画の再生/一時停止を切り替える。
  • アナリティクス トラッキング
  • スクロール テリング
  • Wheel of Fortune UI/UX
  • スナップ ターゲットにアンカー ツールチップが表示されます。
  • タップしてスナップ
  • スナップして表示
  • スナップ音を鳴らす
  • スワイプ UI
  • スワイプ可能なタブまたはカルーセル

その他の調査

Chrome チームは、これらの新しい API を使用して皆様が構築する内容を楽しみにしています。また、スクロール可能なユーザー エクスペリエンスの効率化に、Chrome がお役に立てば幸いです。

リソース: