scrollendイベントでスクロール終了を検知する
scrollendイベントはスクロール操作が完了したときに発火するイベントです。Baseline 2025で主要ブラウザすべてで利用可能になりました。従来のscrollイベントとsetTimeoutを組み合わせた方法と比べて、正確なタイミングでスクロール終了を検知できるようになりました。
はじめに
スクロールが終了したタイミングを検知したいケースがあります。例えば、スクロールが止まった位置をURLに反映したり、スクロール終了後にアニメーションを開始したりする場合です。
しかし、今まではブラウザにスクロールが終了したことを検知するイベントがなく、scrollイベントを監視して擬似的に終了のタイミングを測ることしかできませんでした。
scrollendイベントは、この問題を解決するためにスクロール操作が完了したときに発火してくれるイベントです。Baseline 2025として主要ブラウザすべてで利用可能になりました。
従来の手法
従来はスクロール終了を検知するために、scrollイベントとsetTimeoutを組み合わせる方法が一般的でした。
let scrollTimeout;
element.addEventListener('scroll', () => {
// 前回のタイマーをクリア
clearTimeout(scrollTimeout);
// 一定時間後にスクロール終了と判定
scrollTimeout = setTimeout(() => {
console.log('スクロールが終了しました');
}, 150);
});
しかし、この方法ではタイムアウト値の調整が難しいという課題があります。 値が短すぎるとスクロール中に誤検知し、長すぎると反応が遅くなります。
また、タッチデバイスとマウスホイールではスクロールの特性が異なるため、デバイスによって最適な値が変わってきます。 特にモバイルの慣性スクロールでは、指を離した後もスクロールが続くため、タイマーが切れて誤検知してしまう可能性があります。
scrollendイベント
scrollendイベントを使うと、ブラウザがスクロールの終了を正確に検知してくれます。
element.addEventListener('scrollend', () => {
console.log('スクロールが終了しました');
});
タイムアウト値を気にする必要がなく、シンプルに記述できます。
Playground
アイテム 1
スクロールしてscrollendイベントの発火を確認してください
アイテム 2
スクロールしてscrollendイベントの発火を確認してください
アイテム 3
スクロールしてscrollendイベントの発火を確認してください
アイテム 4
スクロールしてscrollendイベントの発火を確認してください
アイテム 5
スクロールしてscrollendイベントの発火を確認してください
アイテム 6
スクロールしてscrollendイベントの発火を確認してください
アイテム 7
スクロールしてscrollendイベントの発火を確認してください
アイテム 8
スクロールしてscrollendイベントの発火を確認してください
アイテム 9
スクロールしてscrollendイベントの発火を確認してください
アイテム 10
スクロールしてscrollendイベントの発火を確認してください
アイテム 11
スクロールしてscrollendイベントの発火を確認してください
アイテム 12
スクロールしてscrollendイベントの発火を確認してください
アイテム 13
スクロールしてscrollendイベントの発火を確認してください
アイテム 14
スクロールしてscrollendイベントの発火を確認してください
アイテム 15
スクロールしてscrollendイベントの発火を確認してください
アイテム 16
スクロールしてscrollendイベントの発火を確認してください
アイテム 17
スクロールしてscrollendイベントの発火を確認してください
アイテム 18
スクロールしてscrollendイベントの発火を確認してください
アイテム 19
スクロールしてscrollendイベントの発火を確認してください
アイテム 20
スクロールしてscrollendイベントの発火を確認してください
上のエリアをスクロールすると、scroll イベントは連続して発火しますが、scrollend イベントはスクロールが完全に終了したときのみ発火します。
発火条件
scrollendイベントは、ユーザーのスクロール操作(タッチ、マウスホイール、キーボード)が完了したときに発火します。また、scrollTo()やscrollBy()などのAPIによるスクロールや、scroll-snapによるスナップ位置への移動が完了したときにも発火します。
一方で、スクロール位置が変化しなかった場合は発火しません。
Playground
scrollTo() API
scroll-snap
横にスクロールするとスナップします
おわりに
scrollendイベントを紹介しました。
従来のsetTimeoutを使った方法では、適切なタイムアウト値の設定が難しく、デバイスごとの挙動の違いに悩まされることがありました。scrollendイベントにより、ブラウザが正確なタイミングでスクロール終了を通知してくれるようになりました。
Baseline 2025として主要ブラウザすべてで利用可能になったので、スクロール終了の検知が必要な場面があれば採用を検討してみてください。