JavaScriptでスクロール処理を実装するのに便利なscrollIntoViewがAndroid Chromeで動かなくて焦った件
scrollIntoView
スクロール処理の実装に便利な Webページ内の特定の要素を画面に表示される領域までスクロールさせることができます。
しかも、簡潔に実装できます。とっても便利です。
const targetElement = document.getElementById('elementId');
targetElement?.scrollIntoView();
window.scroll
や window.scrollTo
などを利用して、同挙動を実現することは可能です。
ただ、特定の要素の位置座標を取得するロジックが必要になるなど、scrollIntoView
より多くの処理が必要となります。
scrollIntoView
は最新のブラウザでサポートされており、スムーススクロールの設定も簡単にできるので、スクロール処理を実装する際の有力な選択肢になりそうです。
AndroidのGoogle Chromeでの問題(2024年6月時点)
モーダルが閉じる直前に、その裏側の(モーダル表示時に隠れている)コンテンツ内の特定要素を画面に表示される領域までスクロールさせる処理を scrollIntoView
を使って実装していました。
PC、iOS端末の各ブラウザでは上記挙動を実現できますが、AndroidのChromeのみスクロール処理が走っていませんでした。Chrome DevToolsでも再現できず、実機のみ発生する問題のようです。
scrollIntoView
が動作しないケース
- 実行対象が存在しない、または適切に設定されていない
- 実行対象に
display: none
もしくはvisibility: hidden
が適用されている
今回のケースでは、実行対象は存在し、非表示にするCSSも適用されていませんでした。
それなのにスクロールが実行されなかった理由
以下要因が重なってしまったことが原因でした。
- モーダル表示時、
body
にoverflow: hidden
を適用して背景スクロールを抑止していた - モーダル内でスクロールが行えるように
overflow: auto
を設定していた
スクロールが実行されなくなった理由として、想定される処理の流れは以下の通りです。
- 対象となる要素の祖先要素となる
body
にoverflow: hidden
が適用される - スクロールさせられる対象が
body
から、スクロール可能かつ表示状態であるモーダルウィンドウに変わる - 対象要素はモーダルウィンドウ内に存在しないため、スクロールが実行されない
対処方法
body
に overflow: hidden
を設定しない
① 背景スクロールを他の方法で抑止できれば上記設定は不要です。以下の記事が参考になります。
scrollIntoView
の代わりに window.scroll
や window.scrollTo
を使う
② 対象要素を表示領域の上端までスクロールさせるための実装例です。
const targetElement = document.getElementById('elementId');
if (targetElement) {
const rect = element.getBoundingClientRect();
window.scrollTo({ top: rect.top + window.scrollY });
}
scrollIntoView
を利用すれば、上端、中央、下端、近い方の端などオプションで簡単かつ直感的に設定できるメリットがあるので、可能なら①を採用したいところですね。
今回の記事は以上になります。最後まで読んでいただき、ありがとうございました。
Discussion