JavaScriptでWebページを動かす
DOM とは何か
このレッスンで分かること
- ブラウザは HTML の文字列をオブジェクトの木に組み直してから、画面を描いています
- JavaScript が書きかえるのはその木であって、HTML ファイルではありません
コンソールにしか結果を出せなかった
ここまで書いてきた JavaScript は、文字と数と配列とオブジェクトを組み立てるだけのものでした。結果は console.log でコンソールに並びます。ページを開いた人には何も見えません。
第8章からは違います。書いた JavaScript が、目の前のページそのものを書きかえます。肩書きの文字が変わり、作品カードが増え、枠の色が変わります。そのために最初に知っておきたいのが「JavaScript から HTML がどう見えているのか」です。ここを飛ばして書き方だけ覚えると、うまく動かないときに何を疑えばよいのか分からなくなります。
ブラウザは HTML を文字のまま持っていない
ブラウザがサーバーから受け取るのは、ただの長い文字列です。
JavaScript
'<h1>山田 太郎</h1><p class="tagline">Web エンジニアを目指しています</p>'ブラウザはこれを先頭から読み、タグの開きと閉じを見て、どれが誰の中に入っているかを組み立てます。この作業をパースと呼び、できあがったものが DOM です。Document Object Model の頭文字で、日本語にすると「書類をオブジェクトとして表したもの」になります。
大事なのは矢印の向きです。画面は DOM から描かれ、JavaScript が触るのも DOM です。だから JavaScript が DOM を変えれば、画面もそれに合わせて描き直されます。
DOM は入れ子のとおりに親と子の関係を持ちます。プロフィールサイトの上のほうを字下げで表すと、次のような形です。
プレーンテキスト
document
└ html
├ head
└ body
├ header.site-header
│ ├ h1
│ ├ p.tagline
│ └ nav.site-nav
└ main.site-main木の一つひとつの節をノードと呼びます。いちばん上にいるのが document で、ページ 1 枚ぶん全体を表します。ブラウザがあらかじめ用意しているので、console.log と同じで、書けばそこにあります。タグ 1 つぶんの要素ノードは、第7章で書いたオブジェクトとよく似ています。プロパティを持っていて、ドットでつなげば読み書きできます。違うのは、値を書きかえた瞬間にブラウザが画面を描き直してくれるところです。つまり、これまで練習してきたオブジェクトの読み書きが、そのまま画面の操作になります。
書きかえたのに、再読み込みで元に戻る
JavaScript が DOM を変えても、index.html の中身は 1 文字も変わりません。ページを読み込み直せば、元の HTML から DOM が組み直され、変えたぶんは消えます。ここを取り違えると「動いたはずなのに残らない」と悩むことになります。
この違いは、検証ツールで実物を見るといちばん早く飲み込めます。手順は次のとおりです。
- プロフィールサイトをブラウザで開き、どこかを右クリックして「検証」を選ぶ (Mac は
Command + Option + I、Windows はF12でも開きます) - Elements タブを開き、
<body>の左にある三角形をクリックして中を開く <header class="site-header">を開き、<h1>と<p class="tagline">が並んでいるのを確かめる<h1>の行にマウスを乗せると、画面の名前の部分が青く光る。木の 1 行が画面のどこなのかが分かる#worksの中の<div class="work-list">を開き、<article class="work-card">が 3 つ並んでいるのを数える
この 3 枚のカードが、これから JavaScript で増やしたり作り直したりする相手です。
Elements タブの上では、タグや文字をその場で書きかえられます。書きかえると画面がすぐ変わります。これは手で DOM を触っているのと同じことで、再読み込みすれば元に戻るので、こわがらずに試して大丈夫です。
よくある間違い
- ソース表示と Elements タブを同じものだと思う — 「ページのソースを表示」に出るのは、サーバーから届いた元の HTML です。JavaScript で足した要素はそこに出てきません。動いているかどうかは、必ず Elements タブのほうで確かめます
documentを自分でつくる —const document = {};と書くと、ブラウザが用意したものを上書きしてしまい、以降の操作が全部おかしくなります。windowやhistoryも同じ理由で、自分の変数名には使いません
復習ミニクイズ
ブラウザで JavaScript が `document.querySelector("h1").textContent = "変更"` を実行しました。このあと「ページのソースを表示」で見える HTML はどうなっていますか