JavaScript | DOM 操作:DOM 基礎 – window と document の違い

JavaScript JavaScript
スポンサーリンク

window と document の違い

window は「ブラウザタブ(ウィンドウ)そのもの」を表す最上位のオブジェクトです。タイマー、画面サイズ、スクロール、イベント、ストレージ、ネットワークなど“環境”全体を扱います。document は「そのウィンドウ内の現在のページ(DOM ツリー)の入り口」を表し、HTML 要素の取得・作成・挿入・削除など“ページの中身”を扱います。ここが重要です:window は「器」、document は「器の中の文書」。UIの見た目や要素を変えるときは document、タブ全体の状態やイベントを扱うときは window を使います。


役割の直感と代表的な操作

window はタブのライフサイクルや外部とのやり取り、表示領域の情報を扱います。例として、画面サイズを取る、スクロール位置を読む、タイマーで処理を予約する、ロード完了を待つなどが得意です。

// 画面サイズとスクロール
console.log(window.innerWidth, window.innerHeight); // 表示領域の幅・高さ
console.log(window.scrollX, window.scrollY);         // スクロール位置

// タイマー
const id = window.setTimeout(() => console.log("遅延実行"), 500);
window.clearTimeout(id);

// ウィンドウ全体のイベント
window.addEventListener("resize", () => console.log("サイズ変化"));
window.addEventListener("load", () => console.log("外部リソースまで読み込み完了"));
JavaScript

document は DOM ツリー(要素・テキスト・コメント)の根で、要素の取得や生成を行います。ページの中身を操作するときは document を起点にします。

// 要素取得
const title = document.querySelector("#title");
title.textContent = "ようこそ";

// 要素生成・挿入
const p = document.createElement("p");
p.textContent = "説明文";
document.body.append(p);
JavaScript

ここが重要です:画面のサイズ・タブのイベント・タイマーは window、要素・テキスト・属性・クラスの操作は document。


イベントの違いと使い分け

window のイベントは「タブ全体」に関わります。resize、scroll、load、visibilitychange などが典型です。ページの読み込み状況や表示領域の変化に反応したいときに使います。

window.addEventListener("visibilitychange", () => {
  const hidden = document.hidden;
  console.log(hidden ? "非表示" : "表示中");
});
JavaScript

document のイベントは「DOM に対する操作」に向きます。DOMContentLoaded(DOM 構築完了)、クリックや入力などの UI イベントの委譲、選択・フォーカスなど要素中心の反応を設計できます。

document.addEventListener("DOMContentLoaded", () => {
  const form = document.querySelector("form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log("送信を制御");
  });
});
JavaScript

ここが重要です:初期化は DOMContentLoaded(document)で要素取得とイベント登録、画像サイズ依存などリソース完了が必要なら load(window)を使うのが定石です。


グローバル変数・スコープの勘所

ブラウザでは、トップレベルで var で宣言した変数や関数宣言は window のプロパティになります。一方、let/const はグローバルレキシカル環境に置かれ、window にぶら下がりません。無意識にグローバルを作ると衝突や上書きの原因になります。

var legacy = 1;                 // window.legacy として公開される
let modern = 2;                 // window.modern は存在しない
console.log(window.legacy);     // 1
console.log("modern" in window); // false
JavaScript

ここが重要です:グローバルに依存せず、モジュール(type=”module”)や名前空間で管理すると安全です。window を汚さない設計が保守性を高めます。


画面情報とレイアウト(window)と DOM 構造(document)

画面の「枠」を知りたいときは window、ページの「中身」を知りたいときは document を使います。リサイズやスクロールに応じてクラスを書き換えたり、ビューポート判定をして DOM を更新するのが定番パターンです。

// ビューポート幅に応じてレイアウトクラスを切り替え
function updateLayout() {
  const wide = window.innerWidth >= 768;
  document.body.classList.toggle("is-wide", wide);
}
window.addEventListener("resize", updateLayout);
document.addEventListener("DOMContentLoaded", updateLayout);
JavaScript

ここが重要です:window で環境を読み、document で要素を変える。役割を分離すると、処理の見通しがよくなります。


実践例:ナビ固定と初期化の正攻法

ヘッダーをスクロールで固定する UI を考えます。スクロールイベントは window、クラス切り替えは document(要素)で行います。初期化は DOMContentLoaded で安全に。

document.addEventListener("DOMContentLoaded", () => {
  const header = document.querySelector(".header");
  const threshold = 100;

  function onScroll() {
    const fixed = window.scrollY > threshold;
    header.classList.toggle("is-fixed", fixed);
  }

  window.addEventListener("scroll", onScroll);
  onScroll(); // 初期状態を反映
});
JavaScript

ここが重要です:イベントは「誰が発火させるか(window)」、反映は「どこを変えるか(document の要素)」。この分担が読みやすさ・拡張性を生みます。


まとめ

window はブラウザタブの“環境”全体、document はその中の“文書(DOM)”です。サイズ・スクロール・ロード・タイマーなどは window、要素の取得・生成・挿入・属性やクラスの変更は document。初期化は DOMContentLoaded(document)で、リソース完了が必要なら load(window)を使い分けます。環境を読むのが window、中身を変えるのが document——このシンプルな軸を体に入れると、DOM 操作は途端に迷いなく、意図通りに書けるようになります。

タイトルとURLをコピーしました