エラノート エラノート

JavaScript DOM操作入門|要素の取得と変更方法

JavaScript DOM イベント 入門
広告スペース (article-top)

Webページの内容をJavaScriptで動的に変えるには「DOM操作」という技術を使います。ボタンをクリックしたら表示が変わる、フォームの入力内容をチェックするなど、Webサイトのインタラクティブな機能はすべてDOM操作によって実現されています。

DOMとは

DOM(Document Object Model)は、HTMLをJavaScriptから操作するための仕組みです。ブラウザはHTMLを読み込むと、その構造をツリー状のオブジェクト(DOMツリー)として内部的に管理します。JavaScriptはこのDOMツリーを通じてHTML要素にアクセスし、内容の変更やスタイルの操作を行います。

たとえば以下のHTMLは、DOMツリーとして階層的に管理されます。

<div id="app">
  <h1>タイトル</h1>
  <p class="message">こんにちは</p>
</div>

この構造ではdivが親要素、h1pがその子要素です。JavaScriptからはこの階層関係をたどって各要素にアクセスできます。

要素の取得

DOM操作の第一歩は、操作したいHTML要素を取得することです。

getElementById

IDを指定して要素を1つ取得します。

// HTML: <h1 id="title">こんにちは</h1>
const title = document.getElementById("title");
console.log(title.textContent); // "こんにちは"

querySelector / querySelectorAll

CSSセレクタを使って要素を取得します。最も汎用的な方法です。

// 最初に一致する要素を1つ取得
const message = document.querySelector(".message");
const firstItem = document.querySelector("ul li");

// 一致する要素をすべて取得(NodeListが返る)
const allItems = document.querySelectorAll("ul li");

allItems.forEach((item) => {
  console.log(item.textContent);
});

querySelectorはCSSセレクタをそのまま使えるため、柔軟な指定が可能です。

// さまざまなセレクタが使える
document.querySelector("#header .nav-item:first-child");
document.querySelector("input[type='email']");
document.querySelector(".card > p");

要素の内容とスタイルの変更

テキストの変更

const heading = document.querySelector("h1");

// テキスト内容を変更
heading.textContent = "新しいタイトル";

// HTMLを含む内容を変更(XSSに注意)
heading.innerHTML = "重要な<strong>お知らせ</strong>";

textContentは純粋なテキストとして扱い、innerHTMLはHTMLタグも解釈されます。ユーザーの入力をそのままinnerHTMLに入れるとセキュリティ上の問題(XSS)が生じるため、基本的にはtextContentを使いましょう。

スタイルの変更

const box = document.querySelector(".box");

// 個別のスタイルを変更
box.style.backgroundColor = "#f0f0f0";
box.style.padding = "20px";
box.style.borderRadius = "8px";

// CSSクラスの操作(推奨)
box.classList.add("active");
box.classList.remove("hidden");
box.classList.toggle("open"); // あれば削除、なければ追加

個別のスタイル変更よりも、CSSクラスの追加・削除で見た目を変える方が保守性が高くおすすめです。スタイルはCSSファイルに定義し、JavaScriptはクラスの付け替えだけを行うのが理想的です。

属性の操作

const link = document.querySelector("a");

// 属性の取得
console.log(link.getAttribute("href"));

// 属性の設定
link.setAttribute("href", "https://example.com");
link.setAttribute("target", "_blank");

// 属性の削除
link.removeAttribute("target");

// img要素のsrcを変更
const img = document.querySelector("img");
img.src = "new-image.jpg";
img.alt = "新しい画像の説明";

イベント処理

イベント処理は、ユーザーの操作(クリック、入力、スクロールなど)に反応してプログラムを実行する仕組みです。

addEventListener

const button = document.querySelector("#myButton");

button.addEventListener("click", () => {
  console.log("ボタンがクリックされました");
});

よく使うイベント

// クリックイベント
document.querySelector("#btn").addEventListener("click", () => {
  alert("クリックされました");
});

// 入力イベント(リアルタイム)
document.querySelector("#nameInput").addEventListener("input", (event) => {
  const output = document.querySelector("#preview");
  output.textContent = event.target.value;
});

// フォーム送信イベント
document.querySelector("#form").addEventListener("submit", (event) => {
  event.preventDefault(); // デフォルトの送信を止める
  const formData = new FormData(event.target);
  console.log(formData.get("email"));
});

// ページ読み込み完了イベント
document.addEventListener("DOMContentLoaded", () => {
  console.log("ページの読み込みが完了しました");
});

event.preventDefault()は、ブラウザのデフォルト動作(フォーム送信によるページ遷移など)を止めるときに使います。

実践例: カウンターアプリ

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>カウンター</title>
  <style>
    .counter {
      text-align: center;
      margin-top: 50px;
      font-family: sans-serif;
    }
    .count {
      font-size: 48px;
      margin: 20px 0;
    }
    button {
      font-size: 18px;
      padding: 10px 20px;
      margin: 0 5px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div class="counter">
    <h1>カウンター</h1>
    <div class="count" id="count">0</div>
    <button id="decrement">-1</button>
    <button id="reset">リセット</button>
    <button id="increment">+1</button>
  </div>

  <script>
    let count = 0;
    const countDisplay = document.querySelector("#count");

    const updateDisplay = () => {
      countDisplay.textContent = count;
    };

    document.querySelector("#increment").addEventListener("click", () => {
      count++;
      updateDisplay();
    });

    document.querySelector("#decrement").addEventListener("click", () => {
      count--;
      updateDisplay();
    });

    document.querySelector("#reset").addEventListener("click", () => {
      count = 0;
      updateDisplay();
    });
  </script>
</body>
</html>

このコードをHTMLファイルとして保存してブラウザで開くと、動作するカウンターアプリが確認できます。

よくある間違いと対策

間違い1: 要素が取得できない

// NG: HTMLの読み込み前にスクリプトが実行される
// <head>内の<script>で要素を取得しようとすると null になる

// OK: DOMContentLoadedを使う
document.addEventListener("DOMContentLoaded", () => {
  const title = document.querySelector("h1");
  console.log(title.textContent);
});

// OK: scriptタグをbodyの最後に置く
// <body>
//   <h1>タイトル</h1>
//   <script src="main.js"></script>
// </body>

JavaScriptはHTMLよりも先に実行されることがあります。DOMContentLoadedイベントを使うか、<script>タグを<body>の最後に配置しましょう。

間違い2: querySelectorAllの戻り値

// querySelectorAllはNodeListを返す(配列ではない)
const items = document.querySelectorAll(".item");

// NG: 配列メソッドは直接使えない場合がある
// items.map(item => item.textContent);

// OK: forEachは使える
items.forEach((item) => {
  console.log(item.textContent);
});

// OK: 配列に変換してから使う
const itemArray = Array.from(items);
const texts = itemArray.map((item) => item.textContent);

間違い3: イベントリスナーの重複登録

// NG: ループ内で毎回リスナーを登録すると重複する
// for (let i = 0; i < 3; i++) {
//   button.addEventListener("click", handler);
// }

// OK: 一度だけ登録する
function handleClick() {
  console.log("クリック");
}
button.addEventListener("click", handleClick);

DOM操作はJavaScriptの中でも実用性が高い分野です。まずはこの記事のカウンターアプリを改造して、色を変えたりテキストを追加したりして、自分なりの機能を実装してみてください。

広告スペース (article-bottom)

あわせて読みたい