Angularで画面遷移を実装していると、
「別のページへ遷移したのに、前のページのスクロール位置がそのまま残っている」
という現象に遭遇することがあります。
これはAngularの仕様であり、withInMemoryScrolling を利用することで簡単に改善できます。
原因
AngularはSPA(Single Page Application)です。
通常のWebサイトでは、
- 新しいページへ移動 → 一番上から表示
- 戻るボタン → 前回のスクロール位置を復元
というブラウザの標準動作になります。
しかしAngularでは画面を書き換えているだけなので、ブラウザから見ると同じページです。
そのため、何もしないとスクロール位置はそのままになります。
例えば
/home (500pxまでスクロール) ↓ /about
と遷移しても、/about が500px付近から表示されてしまいます。
解決方法
app.config.ts の provideRouter() に withInMemoryScrolling() を追加します。
import { provideRouter, withInMemoryScrolling } from '@angular/router'; provideRouter( routes, withInMemoryScrolling({ scrollPositionRestoration: 'top', }) );
これだけで、ページ遷移時に常にページ先頭から表示されるようになります。
anchorScrollingとは?
withInMemoryScrolling にはアンカーリンク用の機能も用意されています。
provideRouter( routes, withInMemoryScrolling({ scrollPositionRestoration: 'top', anchorScrolling: 'enabled', }) );
anchorScrolling を有効にすると、
/#section1
のようなURLへアクセスした際、
<div id="section1">
まで自動でスクロールしてくれます。
固定ヘッダーがある場合
固定ヘッダーを採用しているサイトでは、アンカーリンクで移動すると見出しがヘッダーの裏に隠れてしまうことがあります。
そのような場合は、スクロール位置をJavaScriptで計算して制御する方法もあります。
const element = document.getElementById(id); const headerOffset = 56; const y = element.getBoundingClientRect().top + window.scrollY - headerOffset; window.scrollTo({ top: y, behavior: 'smooth', });
この方法なら、ヘッダーの高さに応じて自由にスクロール位置を調整できます。
まとめ
- AngularはSPAのため、ページ遷移時にスクロール位置は自動でリセットされない。
withInMemoryScrolling()を利用するとスクロール位置を管理できる。scrollPositionRestoration: 'top'を指定するとページ先頭から表示できる。- アンカーリンクは
anchorScrollingが利用できる。 - 固定ヘッダーがある場合は、自前でスクロール位置を計算すると柔軟に制御できる。