History API を使用して URL を管理することは、優れたウェブアプリの重要な機能です。ただし、この方法のデメリットの一つは、スクロール位置が保存され、さらに重要なのは、履歴を移動するたびに復元されることです。そのため、スクロール位置が自動的に変更されると、見苦しいジャンプが発生することがあります。特に、アプリで遷移が行われる場合や、ページのコンテンツがなんらかの方法で変更される場合は顕著です。最終的には、ユーザー エクスペリエンスが悪化します。
事態を悪化させるのは、この問題に対処する方法がほとんどないことです。Chrome では、scroll
イベントの前に popState
イベントがトリガーされます。つまり、popState
で現在のスクロール位置を読み取り、scroll
イベント ハンドラで window.scrollTo
を使用してその位置を逆にすることができます(ちょっと気持ち悪いですが、少なくとも機能します)。一方、Firefox では popState
の前に scroll
イベントがトリガーされるため、以前のスクロール値を復元できません。ばあ!
ただし、history.scrollRestoration
という解決策が考えられます。2 つの文字列値を受け取ります。auto
は、すべてを現状のままに保ちます(デフォルト値です)。manual
は、ユーザーがアプリの履歴を移動する際に必要となるスクロール変更をデベロッパーが所有することを意味します。必要に応じて、history.pushState()
を使用して履歴エントリを push するときにスクロール位置を追跡できます。
この機能は新しく、試験運用版です(ただし、非常に優れた機能です)。使用前に、この機能が利用可能であることをご確認ください。
if ('scrollRestoration' in history) {
// Back off, browser, I got this...
history.scrollRestoration = 'manual';
}
history.scrollRestoration
は Chrome 46 以降で使用できます。仕様はこちらをご覧ください。
フィードバックをお寄せください。また、scrollRestoration
のサポートを他のベンダーにもご希望の場合は、その旨をお知らせください。