スクロール位置取得の基本 — window.scrollY と el.scrollTop
ページ全体のスクロール量は window.scrollY(縦)/ window.scrollX(横)。特定のスクロール領域(要素)のスクロール量は element.scrollTop / element.scrollLeft で扱います。取得だけでなく、設定(スクロールさせる)も可能です。
画面(ウィンドウ)と要素の違い
- 対象の違い:
- 画面全体:
window.scrollY(縦)、window.scrollX(横) - 要素内スクロール:
el.scrollTop(縦)、el.scrollLeft(横)
- 画面全体:
- 前提条件:
- 要素側: スクロール領域があること(例:
overflow: auto/scroll)。なければ常に0。
- 要素側: スクロール領域があること(例:
- 単位:
- どちらもピクセル。整数で扱われることが多いが、環境によって小数になる可能性もある。
基本のコード例
<div id="viewport-demo" style="height: 1200px; padding-top: 600px;">
<button id="top">トップへ戻る</button>
</div>
<script>
// 画面の縦スクロール量を取得
console.log("window.scrollY:", window.scrollY);
// 画面を移動(上へ戻る)
document.getElementById("top").addEventListener("click", () => {
window.scrollTo({ top: 0, behavior: "smooth" });
});
</script>
HTML<div id="box" style="height: 200px; overflow: auto; border: 1px solid #ccc;">
<div style="height: 800px">中身が長い</div>
</div>
<script>
const box = document.getElementById("box");
// 要素内のスクロール量を取得
console.log("box.scrollTop:", box.scrollTop);
// 要素内を下へスクロール
box.scrollTop = 400; // 即座に指定位置へ
// スムースに動かしたい場合(対応ブラウザ)
box.scrollTo({ top: 600, behavior: "smooth" });
</script>
HTML- ラベル: 画面の移動は
window.scrollTo、要素の移動はel.scrollTopまたはel.scrollTo。
よく使うテンプレート集
ラベル: 「トップへ戻る」ボタンを表示・動作
const backToTop = document.getElementById("backToTop");
window.addEventListener("scroll", () => {
const y = window.scrollY;
backToTop.classList.toggle("is-hidden", y < 300); // 300pxを超えたら出す
});
backToTop.addEventListener("click", () =>
window.scrollTo({ top: 0, behavior: "smooth" })
);
JavaScriptラベル: ある要素を画面の中央付近へスクロール
function scrollIntoViewCenter(el) {
const r = el.getBoundingClientRect();
const centerY = window.scrollY + r.top - (window.innerHeight - r.height) / 2;
window.scrollTo({ top: Math.max(centerY, 0), behavior: "smooth" });
}
JavaScriptラベル: スクロールコンテナ内で特定アイテムへ移動
function scrollItemIntoContainer(container, item) {
const cr = container.getBoundingClientRect();
const ir = item.getBoundingClientRect();
const offsetTopInContainer = ir.top - cr.top + container.scrollTop;
container.scrollTo({ top: offsetTopInContainer, behavior: "smooth" });
}
JavaScriptラベル: スクロールに応じてヘッダーを縮める
const header = document.querySelector("header");
window.addEventListener("scroll", () => {
const y = window.scrollY;
header.classList.toggle("compact", y > 80);
});
JavaScript実務でのコツ
- ラベル: スムーススクロールの使い分け
- 画面は
window.scrollTo({ top, behavior: "smooth" })。要素はel.scrollTo({ top, behavior: "smooth" })。
- 画面は
- ラベル: スクロール可能条件の確認
- 要素で
scrollTopを使うときはoverflow: auto/scrollと内容の高さが要素の高さを超えていることが必須。
- 要素で
- ラベル: スクロール判定の最適化
scrollイベントは高頻度。処理は軽く、必要ならrequestAnimationFrameやスロットリング(setTimeout)で負荷軽減。
- ラベル: 相対座標と絶対座標
getBoundingClientRect()は画面基準。ページ基準へ変換するならwindow.scrollX/scrollYを加算。
- ラベル: アクセシビリティ
- 大きくスクロールを伴うUIは「フォーカスの移動」や「論理順序」を崩さない設計を。
ありがちなハマりポイントと対策
- ラベル: 値が常に 0(要素側)
- 原因: スクロール領域がない(
overflow未設定、内容が短い)。 - 対策:
overflowを設定し、内容の高さを確認。
- 原因: スクロール領域がない(
- ラベル:
scrollの処理が重い- 対策: 計算を最小化し、
requestAnimationFrameでまとめて実行。激しいDOM操作を避ける。
- 対策: 計算を最小化し、
- ラベル: モバイルのアドレスバーで数値が揺れる
- 対策: ビューポートの変動を前提に少し余裕を持つ、重要判定はしきい値にマージンを取る。
- ラベル: スクロール位置がずれる(固定ヘッダー)
- 対策: 目的位置からヘッダーの高さを差し引いて調整。
練習問題(手を動かして覚える)
<header id="hdr" style="position: fixed; top: 0; left: 0; right: 0; height: 60px; background: #eee;">Header</header>
<main id="content" style="margin-top: 60px;">
<p style="height: 1000px">長いコンテンツ1</p>
<p id="anchor" style="height: 600px; background: #f7f7f7;">ここに移動したい</p>
<p style="height: 1000px">長いコンテンツ2</p>
</main>
<button id="to-anchor">アンカーへ</button>
<button id="back">トップへ</button>
<script>
const toAnchor = document.getElementById("to-anchor");
const back = document.getElementById("back");
const anchor = document.getElementById("anchor");
const hdr = document.getElementById("hdr");
// 1) 画面スクロール量を表示
window.addEventListener("scroll", () => {
console.log("scrollY:", Math.round(window.scrollY));
});
// 2) 固定ヘッダー分を差し引いてアンカーへ
toAnchor.addEventListener("click", () => {
const r = anchor.getBoundingClientRect();
const top = window.scrollY + r.top - hdr.offsetHeight;
window.scrollTo({ top, behavior: "smooth" });
});
// 3) トップへ戻る
back.addEventListener("click", () => {
window.scrollTo({ top: 0, behavior: "smooth" });
});
</script>
HTML直感的な指針
- 画面は
window.scrollY/scrollTo、要素はel.scrollTop/scrollTo。 - 「スクロールできる条件」を満たしてから、位置を計算・設定。
- イベント処理は軽く、スムーススクロールや固定ヘッダー補正を前提に組む。
