「ボタンを押したら文字が変わる」「タブをクリックしたら別の内容が表示される」「エラーメッセージがその場で出る」。
こういう“動くWebページ”は、すべてJavaScriptが画面の中身(HTML)を書き換えて実現しています。
この「画面の中身にアクセスして、書き換える」ための仕組みが DOM(Document Object Model) です。
この記事では、初心者の方でもわかるように
- DOMってそもそも何者?
- ページの中から特定の要素をどうやって取ってくるの?
- テキストや属性をどうやって書き換えるの?
- 新しいHTMLをどうやって追加・削除するの?
という基本を順番に解説します。
1つずつ読めば、jQueryなしでも自分で画面をいじれるようになります。
が、記事が少し長くなりすぎました。ちょっとずつ読んでください。
目次
1. DOMってなに?ざっくりイメージでOK
ブラウザは、HTMLをそのまま文字列として持っているわけではありません。
HTMLを読み込んだとき、ブラウザの中ではそれが「ツリー構造のオブジェクト」として整理されます。
このツリー構造こそが DOM(Document Object Model) です。
document… ページ全体を表す一番上の親- その下に
<html>要素 <html>の下に<head>と<body><body>の下に<div>,<p>,<ul>… とどんどん子どもがつながっていく
木(ツリー)で考えるとわかりやすいです。
親がいて、子どもがいて、兄弟がいる。DOMは「HTMLをオブジェクトとして扱いやすくした家系図」だと思ってください。
DOMをさわる=この家系図の中から特定の要素を見つけて、読んだり、書き換えたり、増やしたり、消したりすることです。
2. document って何者?
JavaScript から DOM にアクセスするときの入口が document です。
// ページ全体にアクセスするための入り口オブジェクト
console.log(document);
document はブラウザが自動で用意してくれるオブジェクトなので、自分で作る必要はありません。
ここから「特定の要素を探す」「中身を変える」などをやっていきます。
3. 要素を「取得する」基本パターン
まずは「ページの中から目的のパーツをひっぱってくる」ことができないと何も始まりません。
ここがDOM操作の第1歩です。
3-1. getElementById:idで1つだけ取る
HTML側で id が付いている要素は、JavaScriptからピンポイントで取得できます。
HTML例:
<div id="mainArea">
<p>ようこそ!</p>
</div>
JavaScript例:
// id="mainArea" の要素を取得
const mainBox = document.getElementById("mainArea");
// コンソールに表示して中身を確認
console.log(mainBox);
id は基本的に1ページ内でユニーク(かぶらない)であるべきなので、戻ってくるのは「1個の要素」です。
もし同じidを複数つけていたら、最初に見つかったものだけ返ってきます。
これは初心者がハマりがちなポイントです。
3-2. getElementsByTagName:タグ名でまとめて取る
特定のタグ(例:<li> だけ)をぜんぶ取りたいときはこれ。
HTML例:
<ul id="menuList">
<li>ホーム</li>
<li>ブログ</li>
<li>お問い合わせ</li>
</ul>
JavaScript例:
// ページ全体から <li> を全部集める
const allItems = document.getElementsByTagName("li");
// 何件取れたか
console.log(`liは全部で ${allItems.length} 個あります`);
// 1つずつ中身を表示
let index = 0;
for (const item of allItems) {
console.log(`li[${index}] のテキストは「${item.textContent}」です`);
index++;
}
ここで返ってくるのは HTMLCollection という”配列っぽい集合”です。length で数えられるし、for-ofで回せます。
さらに応用として「特定エリアの中だけで探す」こともできます。
たとえば、上の <ul id="menuList"> の中だけを検索する場合:
const menu = document.getElementById("menuList");
const menuItems = menu.getElementsByTagName("li");
console.log(`menuListの中のliは ${menuItems.length} 個です`);
ポイント:
document.getElementsByTagName(...)→ ページ全体が対象ある要素.getElementsByTagName(...)→ その要素の「内側だけ」が対象
これ、DOMを扱ううえですごく大事です。「どこから探すか」で結果が変わります。
3-3. getElementsByClassName:クラス名でまとめて取る
class="highlight" のようなクラスは、複数の要素に同じクラスを付けられます。
だから戻り値も複数セット(HTMLCollection)です。
HTML例:
<div class="article highlight">
<h2 class="sectionTitle">DOMって何?</h2>
<p>説明テキスト...</p>
</div>
<div class="article">
<h2 class="sectionTitle highlight">要素を探す方法</h2>
<p>説明テキスト...</p>
</div>
JavaScript例:
// "highlight" クラスがついている要素をぜんぶ取得
const markedList = document.getElementsByClassName("highlight");
console.log(`highlight付きの要素は ${markedList.length} 個あります`);
for (const box of markedList) {
console.log(box);
}
// 複数クラスで絞り込みもできる(スペース区切り)
const specialList = document.getElementsByClassName("article highlight");
console.log(
`article かつ highlight の要素は ${specialList.length} 個あります`
);
複数クラスでの検索は "classA classB" のようにスペースでつなげます。
書かれている順番は関係ありません(class="article highlight" でも class="highlight article" でもヒットします)。
3-4. getElementsByName:name 属性で取得する
主にフォーム要素(<input>など)で使います。
戻り値は NodeList という”これも配列っぽいもの”です。
HTML例:
<form>
<label>
<input type="checkbox" name="osGroup" value="win"> Windows
</label>
<label>
<input type="checkbox" name="osGroup" value="mac"> macOS
</label>
<label>
<input type="checkbox" name="osGroup" value="linux"> Linux
</label>
</form>
JavaScript例:
// name="osGroup" がついた要素をまとめて取得
const osOptions = document.getElementsByName("osGroup");
console.log(`OSの選択肢は ${osOptions.length} 個あります`);
for (const opt of osOptions) {
console.log(opt); // <input ...> 要素が順番に出てくる
}
NodeList も for...of で回せますし、length で数えられます。
3-5. いま主流はこれ:querySelector / querySelectorAll
正直、現場だとまずこれを使います。
querySelector(セレクタ)
→ CSSセレクタで指定した「最初の1個だけ」を返すquerySelectorAll(セレクタ)
→ CSSセレクタで指定した「すべて」を返す(NodeList)
セレクタは普段CSSで書くやつと同じです。#id名, .class名, input[type="text"], div > p みたいな指定ができます。
HTML例(フォーム):
<form id="userForm">
<div class="formRow">
<label for="userName">お名前</label>
<input type="text" id="userName" name="userName" />
</div>
<div class="formRow">
<label for="userCity">住所</label>
<input type="text" id="userCity" name="userCity" />
</div>
<div class="formRow">
<input type="checkbox" id="optWin" class="osCheck" name="osType" />
<label for="optWin">Windows</label>
</div>
<div class="formRow">
<input type="checkbox" id="optMac" class="osCheck" name="osType" />
<label for="optMac">macOS</label>
</div>
</form>
JavaScript例(1つだけ欲しいとき):
// 最初の <input> 要素を1つだけ取る
const firstInput = document.querySelector("input");
console.log(firstInput);
// id指定(#〜)
const macCheckbox = document.querySelector("#optMac");
console.log(macCheckbox);
// class指定(.〜)
const anyOsCheck = document.querySelector(".osCheck");
console.log(anyOsCheck);
// 属性指定([type="text"])
const firstTextField = document.querySelector('input[type="text"]');
console.log(firstTextField);
JavaScript例(全部ほしいとき):
// .osCheck クラスがついたチェックボックスを全部取得
const allOsChecks = document.querySelectorAll(".osCheck");
console.log(`.osCheck は ${allOsChecks.length} 個あります`);
for (const checkbox of allOsChecks) {
console.log(checkbox.id); // optWin / optMac ...
}
覚えておきたいこと
querySelectorは「1個だけ」(先頭のもの)querySelectorAllは「全部」(NodeList)- CSSセレクタで書けるので、これだけでほぼ何でも取れる
→ 正直これさえ使えれば、上のgetElementByIdなどは「レガシーを読むとき用+一部高速にしたいとき用」くらいの感覚になってきています。
4. 取得した要素の中身を読む・書き換える
要素を取ってこれたら、次は「中身をいじる」ことができます。
ここが一番ワクワクするところです。
4-1. テキストを書き換える:textContent
textContent は、その要素のテキストだけを読み書きできます(HTMLタグはそのまま文字として扱われます)。
HTML例:
<p id="statusMessage">このメッセージは最初の表示です。</p>
<p id="resultMessage"></p>
JavaScript例:
const msg = document.getElementById("statusMessage");
// 読み取り
console.log(msg.textContent); // "このメッセージは最初の表示です。"
// 書き換え
const output = document.getElementById("resultMessage");
output.textContent = "JavaScriptからメッセージを書き込みました!";
textContentは テキスト専用。タグは解釈しないので安全。- 実務では
textContentを使うことが多いです。innerTextはブラウザによるレイアウトの影響を受けたりするので、まずはtextContentから覚えてOKです。
4-2. HTMLごと差し込む:innerHTML
「太字にしたい」「リンクを入れたい」など、HTMLタグもまとめて差し込みたいときは innerHTML を使います。
HTML例:
<div id="infoBox"></div>
JavaScript例:
const box = document.getElementById("infoBox");
// HTMLごと差し込む
box.innerHTML = `
<strong>お知らせ:</strong>
<span class="warn">メンテナンスは本日23時からです。</span>
`;
innerHTMLは、その要素“の中身だけ”を置き換えます- つまり
<div id="infoBox"> ...ここが丸ごと上書きされる... </div>の「…」の部分に注入されるイメージです
注意点:
ユーザーから入力された文字列などをそのまま innerHTML に入れると、XSS(スクリプト埋め込み)みたいなセキュリティリスクになる場合があります。
信頼できない文字列は textContent で入れるのが安全です。
4-3. 要素ごと取得/置き換えたいとき:outerHTML
outerHTML は「その要素自身を含めたHTML丸ごと」を読み書きします。
<p id="replaceTarget">ここは最初の文章です。</p>
const target = document.getElementById("replaceTarget");
// いまのHTMLを確認
console.log(target.outerHTML);
// この<p>自体を別の要素に置き換える
target.outerHTML = `<div class="updated">このブロックは差し替え済みです。</div>`;
これを使うと、元の要素そのものが別のタグにすり替わります。
最初は「へぇ、こういうこともできるんだ」くらいでOKです。
5. 属性(id, class, type など)を読む・変更する
フォームやボタンを操作するときによく使います。
ここからが「ちょっとだけ開発者っぽい」感じになります。
5-1. 属性を読む:getAttribute / .属性名
<input type="text" id="userEmail" class="inputField large" />
const emailInput = document.getElementById("userEmail");
// ① どのtypeか?
console.log(emailInput.getAttribute("type")); // "text"
// ② class名は?
console.log(emailInput.getAttribute("class")); // "inputField large"
// プロパティとして読むことも可能
console.log(emailInput.id); // "userEmail"
console.log(emailInput.type); // "text"
element.getAttribute("属性名")- もしくは
element.属性名で読めるものも多い(id,className,typeなど)
5-2. 属性を書き換える:setAttribute / 代入
// classを追加・変更
emailInput.setAttribute("class", "inputField large is-error");
// idを変える(あまり多用はしないけど可能)
emailInput.id = "userEmailField";
// data属性など自由な属性も設定できる
emailInput.setAttribute("data-role", "login-email");
5-3. 属性を削除する:removeAttribute
// class属性そのものを消す
emailInput.removeAttribute("class");
5-4. すべての属性を確認する
開発・デバッグのときに便利です。
const emailInput = document.getElementById("userEmail");
// すべての属性名を配列でもらう
const attrNames = emailInput.getAttributeNames();
for (const name of attrNames) {
const value = emailInput.getAttribute(name);
console.log(`属性名: ${name} / 属性値: ${value}`);
}
6. 新しい要素を作って、ページに追加する
ここからいよいよ「動的なWebサイト」の入口です。
「ボタンを押したら新しい行を追加する」とか「エラーメッセージを下に出す」とか、全部これ。
6-1. 要素を新しく作る:document.createElement()
// <li> を新しく作る
const newItem = document.createElement("li");
// 中身のテキストをセット
newItem.textContent = "新しく追加されたメニューです";
ここまでだと、まだメモリの中にあるだけで、画面には出ていません。
次に「どこに差し込むか」を決めて追加します。
6-2. 子要素として追加する(末尾に):append / appendChild
HTML例:
<ul id="menuArea">
<li>ホーム</li>
<li>ブログ</li>
</ul>
JavaScript例:
const menuArea = document.getElementById("menuArea");
const extraItem = document.createElement("li");
extraItem.textContent = "お問い合わせ";
// リストの一番最後に追加
menuArea.append(extraItem); // または menuArea.appendChild(extraItem);
append は複数まとめて追加できたり、テキストも渡せたりする「今っぽい」メソッドです。appendChild は昔からあるメソッドで、基本は1個ずつ要素ノードを追加します。
6-3. 先頭に入れたいとき:prepend
const topItem = document.createElement("li");
topItem.textContent = "👑 イチオシ";
menuArea.prepend(topItem); // リストの先頭に差し込む
6-4. 特定の要素の「前」や「後ろ」に差し込む:before / after
const note = document.createElement("p");
note.textContent = "この下のメニューは随時更新されます。";
menuArea.before(note); // <ul> の直前に差し込む
after を使えば直後に置けます。
7. 要素を削除する・置き換える
更新UIには削除も置換もよく使います。(例えば「通知を閉じる」)
7-1. 消す:remove()
<p id="alertBox" class="notice">
メールアドレスを入力してください
</p>
const alertBox = document.getElementById("alertBox");
// この<p>自体を削除
alertBox.remove();
7-2. 子どもを消す:removeChild()
<ul id="todoList">
<li>牛乳を買う</li>
<li>レポートを提出</li>
</ul>
const todoList = document.getElementById("todoList");
// 2つ目の<li>を取得して削除
const secondTask = todoList.querySelectorAll("li")[1];
todoList.removeChild(secondTask);
7-3. 置き換える:replaceWith
<p id="oldMessage">このメッセージは古いです</p>
const oldMsg = document.getElementById("oldMessage");
// 新しい要素を作る
const newMsg = document.createElement("div");
newMsg.className = "updatedInfo";
newMsg.textContent = "このエリアは最新の内容に置き換わりました。";
// 置換
oldMsg.replaceWith(newMsg);
これで <p id="oldMessage">…</p> が <div class="updatedInfo">…</div> にまるごと入れ替わります。
8. よくある「初心者がつまづくポイント」
最後に、実務ですごくありがちな勘違いも一緒にまとめます。
ここ、共感してもらえると思います。
8-1. 「HTMLを書き換えたのに反映されない」
console.log でしか確認してない、というパターンが多いです。console.log はあくまで“今その瞬間のオブジェクトの状態”を見るもの。
実際に textContent = "..." や append(...) をして、ブラウザ画面側が変わるところまでやって初めて「画面が更新」されます。
8-2. innerHTML と textContent の違いがわからない
textContent = "<strong>太字</strong>"
→ そのまま「<strong>太字</strong>」という文字になる(タグは効かない)innerHTML = "<strong>太字</strong>"
→<strong>として認識され、実際に太字になる
安全性と見た目、どっちを優先したいかで使い分けます。
8-3. querySelectorAll の結果を直接 .textContent = … しようとしてエラー
querySelectorAll は“複数”をまとめたNodeListです。
個別にアクセスするときはループで回すか、[0] のように一つ指定してから操作します。
const items = document.querySelectorAll(".newsItem");
// items.textContent = "更新しました" ← これはエラー
items[0].textContent = "更新しました"; // こうならOK
9. まとめ
- DOMは「ブラウザがHTMLをオブジェクト化したもの」。木のような親子関係を持つ。
documentはDOMにアクセスする入り口。- 要素の取得は
querySelector/querySelectorAllがいまの主流。
それ以外(getElementByIdなど)も読む力として覚えておくと◎ textContent/innerHTML/outerHTMLで中身や構造を書き換えられる。setAttribute/removeAttributeで属性(class, id, typeなど)を操作できる。createElement+append/prepend/before/afterで新しい要素を差し込める。remove()やreplaceWith()で要素ごと消したり置き換えたりできる。
ここまで理解できれば、もう「静的なHTMLしか作れない人」ではなくなります。
小さなインタラクション(エラーメッセージの表示、タブ切り替え、モーダルの表示/非表示)なら自力で書ける入口に立っています。
次のステップとしては、「イベント」(クリックされたら実行する、入力されたら実行する)を学ぶと、一気に“動くサイトを作れる人”に近づきます。
そこに進む準備として、今ここで覚えた「要素を見つける力」と「中身を書き換える力」はめちゃくちゃ重要です。あなたはもう、その一歩をちゃんと踏み出せていますよ。



