History API - スクロールの復元

History API を使用して URL を管理することは、優れたウェブアプリの重要な機能です。ただし、この方法のデメリットの一つは、スクロール位置が保存され、さらに重要なのは、履歴を移動するたびに復元されることです。そのため、スクロール位置が自動的に変更されると、見苦しいジャンプが発生することがあります。特に、アプリで遷移が行われる場合や、ページのコンテンツがなんらかの方法で変更される場合は顕著です。最終的には、ユーザー エクスペリエンスが悪化します。

事態を悪化させるのは、この問題に対処する方法がほとんどないことです。Chrome では scroll イベントの前に popState イベントがトリガーされます。つまり、popState で現在のスクロール位置を読み取り、scroll イベント ハンドラで window.scrollTo を使用してその位置を逆にすることができます(ちょっと気持ち悪いですが、少なくとも機能します)。一方、Firefox では popStatescroll イベントがトリガーされるため、以前のスクロール値を復元できません。ばあ!

ただし、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 のサポートを他のベンダーにもご希望の場合は、その旨をお知らせください。