HOWTO · JavaScript
JavaScript で ID までスクロール
同じページ内の移動にはネイティブアンカーを使えます。通常は`scrollIntoView()`で要素までスクロールし、位置を細かく調整する場合は`window.scrollTo()`でオフセットを指定します。入れ子になったコンテンツでは、スクロールコンテナ内の移動方法も解説します。
このページの内容
IDで要素までスクロールするには、document.getElementById()で要素を取得し、そのscrollIntoView()メソッドを呼び出します。同じページ内の通常の移動なら、<a href="#details">Details</a>のようなHTMLアンカーだけで十分なことがよくあります。JavaScriptは、移動先や操作を動的に決める場合に便利です。以下の例では、要素への直接スクロール、ドキュメント内の位置を調整したスクロール、コンテナ内のスクロールを説明します。
JavaScriptでIDの要素までスクロールするにはelement.scrollIntoView()メソッドを使う
既知の要素をブラウザーに表示させる場合は、scrollIntoView()が簡潔な方法です。要素を表示領域の先頭、中央、末尾に合わせられるほか、滑らかなスクロールも指定できます。
<a href="#details">Go to details</a>
<section id="details">
<h2>Details</h2>
<p>The browser navigates to this section.</p>
</section>
<button id="show-details" type="button">Show details smoothly</button>
<script>
const details = document.getElementById("details");
document.getElementById("show-details").addEventListener("click", () => {
details.scrollIntoView({ behavior: "smooth", block: "start" });
});
</script>
これはブラウザー上のページを示す例であり、実行例ではありません。実際の記事で使う場合は、対象のIDが一意になるようにしてください。リンクを通常のページ内ナビゲーションとして機能させるならネイティブのアンカーを使い、イベントハンドラーなどのアプリケーションロジックからスクロールを開始するならscrollIntoView()を呼び出します。コード例に表示されるラベルは英語のままです。「Go to details」はDetailsセクションへのリンクで、「Show details smoothly」はブラウザーにそのセクションを滑らかにスクロールして表示するよう求めるボタンです。オプションオブジェクトを使うと、以前の真偽値形式を避けながら、意図する位置合わせを明確に指定できます。behaviorには"smooth"または"auto"を指定でき、blockとinlineはそれぞれ垂直方向と水平方向の位置合わせを制御します。
JavaScriptでIDの要素までスクロールするには座標を手動で計算してwindow.scrollTo()メソッドを使う
固定ヘッダーの下に余白を設けるなど、対象の位置を独自に調整したい場合はwindow.scrollTo()を使います。getBoundingClientRect().topはビューポート上端からの距離です。そのため、現在のドキュメントのスクロール位置を加えてドキュメント上の座標に変換します。対象をヘッダーの下に配置するには、希望する余白を差し引きます。
function getScrollTopForTarget(targetTopInViewport, currentScrollY, headerGap) {
return targetTopInViewport + currentScrollY - headerGap;
}
const targetTop = 420;
const currentScrollY = 300;
const headerGap = 64;
console.log(getScrollTopForTarget(targetTop, currentScrollY, headerGap));
この自己完結したJavaScriptの計算例は、ここでは実行していません。ブラウザーのコードでは、測定した値を渡し、計算結果をwindow.scrollTo({ top, behavior: "smooth" })のtop値として使います。
<button id="jump" type="button">Open the section</button>
<div style="height: 900px"></div>
<section id="target"><h2>Target section</h2></section>
<script>
document.getElementById("jump").addEventListener("click", () => {
const target = document.getElementById("target");
const headerGap = 64;
const top = target.getBoundingClientRect().top + window.scrollY - headerGap;
window.scrollTo({ top, behavior: "smooth" });
});
</script>
このHTMLはブラウザー上のページを示す例であり、実行結果を示すものではありません。固定ヘッダーが占める領域に合わせてheaderGapを調整してください。特別な位置調整が不要なら、座標の扱いが少ないscrollIntoView()を使えます。
JavaScriptでIDの要素までスクロールするにはscrollLeftとscrollTopを使うscrollTo()メソッドを利用する
scrollLeftとscrollTopは、スクロール可能な要素の現在の水平方向および垂直方向のスクロール位置を表します。ドキュメント内にある任意の対象IDの位置を示すものではありません。入れ子になったスクロールパネル内の対象を表示するには、その対象に対してscrollIntoView()を呼び出します。パネルの座標を直接設定するには、パネルのscrollTo()メソッドを呼び出します。
<div id="panel" style="height: 180px; overflow: auto">
<div style="height: 400px">Scrollable panel content</div>
<p id="panel-target">Target inside the panel</p>
</div>
<button id="panel-button" type="button">Scroll panel to target</button>
<script>
const panel = document.getElementById("panel");
const panelTarget = document.getElementById("panel-target");
document.getElementById("panel-button").addEventListener("click", () => {
panelTarget.scrollIntoView({ behavior: "smooth", block: "start" });
});
</script>
このブラウザー上のページを示す例は実行していません。設定したいコンテナの座標が分かっている場合、panel.scrollTo({ left: 0, top: 200, behavior: "smooth" })でパネルの位置を設定できます。panel.scrollTopやpanel.scrollLeftを読み取ると現在位置を確認できますが、これらの値は対象の座標ではありません。
まとめ
同じページ内の通常の移動には、ネイティブのhref="#id"リンクを使います。選択した要素を表示するにはscrollIntoView()を使い、スクロール可能なコンテナ内の対象にも適用できます。固定ヘッダーを避けるなど、ドキュメント内の対象位置に独自の余白が必要な場合は、座標を計算してwindow.scrollTo()を使います。scrollLeftとscrollTopはスクロール可能な要素の位置を表すもので、IDの位置を特定するものではありません。