JavaScript 逆引き集 | スクロール位置取得

JavaScript JavaScript
スポンサーリンク

スクロール位置取得の基本 — 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
  • 「スクロールできる条件」を満たしてから、位置を計算・設定。
  • イベント処理は軽く、スムーススクロールや固定ヘッダー補正を前提に組む。
タイトルとURLをコピーしました