--- title: ドキュメントの操作 slug: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents tags: - API - Article - Beginner - CodingScripting - DOM - Document - Document Object Model - JavaScript - Learn - Navigator - WebAPI - Window translation_of: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents ---
ウェブページやアプリを書く場合に、最も多く必要になるのはウェブ文書をどうかして操作する事でしょう。これは普通ドキュメントオブジェクトモデル (Document Object Model、DOM) によって為され、DOM は HTML とスタイルに関する情報を {{domxref("Document")}} オブジェクトを多用して操作する一連の API です。この記事では、DOM の使い方を詳しく見ながら、面白い方法であなたの環境を変える事ができる興味深い他の API もいくつか見ていきます。
前提条件: | 基本的なコンピュータに関する知識と理解、HTML と CSS、JavaScript—JavaScript のオブジェクトについても—基本を理解していること |
---|---|
目的: | DOM API の核と、DOM と共によく利用される API、ドキュメントの操作について詳しくなること |
ウェブブラウザーはとてもたくさんの動いている部品からなるソフトウェアの複雑な集合体で、部品の多くはウェブ開発者の JavaScript からでは制御したり操作することはできません。こんな制約はよろしくないと思う方もいるかもしれませんが、ブラウザが保護されているのには十分な理由があって、これは主にセキュリティ関係のためです。もしあるウェブサイトがあなたが保存しているパスワードやその他の秘密情報にアクセスできて、あなたのふりをして他のサイトにログインできたらどうですか?
制限はあっても、ウェブ API は、ウェブページ上でいろいろ素敵な事をできるように、たくさんの機能を提供してくれます。あなたのコードからよく参照するであろう目に見える代物はほんのわずかです — 下の図を見て下さい、この図はウェブページの表示に直接関与しているブラウザーの主要なパーツを表わしています:
この記事では主にドキュメントの操作に着目しますが、それ以外の役に立つこともちょっとお見せしていきます。
あなたのブラウザーの一つ一つのタブに今読み込まれているドキュメントは、ドキュメントオブジェクトモデルとして表現されます。これは HTML の構造に対してプログラム言語から簡単にアクセスできるようにブラウザーが作成する、"木構造"による表現です — 例えば、ページをレンダリングする際にはブラウザー自体がスタイルや他の情報を適切な要素に適用するために DOM を使い、ページのレンダリングが終わった後にはあなたのような開発者が JavaScript を使って DOM を操作できます。
dom-example.html にちょっとした例を作成しました(ライブ実行もどうぞ)。ブラウザーから開いてみてください — これはとても簡素なページで、{{htmlelement("section")}} 要素の中に画像が一つと、一つのリンクを含む一つのパラグラフがあります。HTML のソースはこんな感じです:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Simple DOM example</title> </head> <body> <section> <img src="dinosaur.png" alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth."> <p>Here we will add a link to the <a href="https://www.mozilla.org/">Mozilla homepage</a></p> </section> </body> </html>
一方これの DOM はこんな具合になります:
注記: この DOM ツリーの図は Ian Hickson の Live DOM viewer を使って作成しました。
これを見ると、それぞれのドキュメント内の要素とちょっとばかりのテキストそれぞれが、ツリーの中でそれ自身のエントリーがあるのがわかるでしょう — これら一つ一つをノードと呼びます。またノードの種類を示す語や、ノードそれぞれの関係によりツリーでの位置があるのがわかるでしょう:
HTML
ノードになります。(SVG や独自の XML といった他のマークアップ言語の方言では異なるルート要素の場合があります)IMG
は SECTION
の子ノードとなります。IMG
は SECTION
の子ノードであり、子孫ノードでもあります。IMG
は BODY
の二段階内側にあるので BODY
の子ノードではありませんが、BODY
の子孫ノードではあります。BODY
は SECTION
ノードの親ノードになります。IMG
と P
は兄弟ノードになります。これからコードを見ていくとこういう語が頻出するので、DOM を使い始める前に、これらの用語をしっかり覚えておくと良いでしょう。CSS の勉強をしているときも、これらの語をみかけることでしょう(子孫セレクター、子セレクターとか)。
DOM 操作の学習スタートは、実践的な例から始めましょう。
<script></script>
要素を、閉じ</body>
タグのすぐ上に追加して下さい。const link = document.querySelector('a');
link.textContent = 'Mozilla Developer Network';
link.href = 'https://developer.mozilla.org';
JavaScript あるあるですが、要素を選んで変数に保存する方法にはいろんなやり方があることを頭に入れておいて下さい。{{domxref("Document.querySelector()")}} を使うのが推奨される今風のやり方ですが、これは CSS セレクタと同じ方法で要素を選別できるからです。上記の querySelector()
呼び出しでは文書に現われる最初の {{htmlelement("a")}} がマッチします。もし複数の要素を選択し処理したいのであれば {{domxref("Document.querySelectorAll()")}} を使うことができて、これはセレクタとマッチする全ての要素にマッチし、それらへの参照を {{domxref("NodeList")}} と呼ばれる配列のようなオブジェクトに保存します。
要素への参照を得るための、次のような古いやり方もあります:
id
属性値を使って選択します。<p id="myId">My paragraph</p>
こんなのです。 関数の引数に ID を渡します。 const elementRef = document.getElementById('myId')
こんな具合です。<p>
、全部の <a>
など。 要素の種別は関数の引数として渡します。const elementRefArray = document.getElementsByTagName('p')
こんな具合です。上の二つは querySelector()
のような今風のメソッドよりも古いブラウザーで動作しますが、あまり便利ではありません。これ以外にどんなやり方があるかは、あなた自身で探してみて下さい!
ここまでで、どんな事ができるのかちょっと見えてきたと思いますが、さらに進んで新しい要素を作る方法を見ていきましょう。
const sect = document.querySelector('section');
const para = document.createElement('p'); para.textContent = 'We hope you enjoyed the ride.';
sect.appendChild(para);
const text = document.createTextNode(' — the premier source for web development knowledge.');
const linkPara = document.querySelector('p'); linkPara.appendChild(text);
以上が DOM にノードを追加するために必要な事のほぼ全てです — 動的なインターフェースを作成する際(あとでそういう例題をいくつか見ていきます)これらのメソッドをめっちゃ使う事になるでしょう。
ノードを移動したり、DOM から削除したくなる場合があると思います。勿論できます。
リンクを含むパラグラフを section の最後に移動したい場合は、こうするだけです:
sect.appendChild(linkPara);
これでパラグラフは section の一番下に移動します。コピーが作成されるだけじゃないのかとお思いかもしれませんが、この場合は違います — linkPara
はパラグラフへの参照の唯一のコピーです。もしコピーをした上で同じように追加をしたいのであれば、 {{domxref("Node.cloneNode()")}} をかわりに使う必要があります。
削除したいノードとその親ノードへの参照を得ていれば、ノードを削除するのも非常に簡単です。今の例題であれば、以下のように {{domxref("Node.removeChild()")}} を使うだけです:
sect.removeChild(linkPara);
よくあるケースですが、削除したいノードそのものへの参照しかない場合に、{{domxref("ChildNode.remove()")}} が使えます:
linkPara.remove();
このメソッドは、古いブラウザではサポートされていません。 ノードにそれ自体を削除するように指示するメソッドはないので、次のようにしなければなりません。
linkPara.parentNode.removeChild(linkPara);
上の行をあなたのコードに追加してやってみて下さい。
いろんなやり方で CSS スタイルを JavaScript から操作することができます。
まず、ドキュメントに付随する全部のスタイルシートのリストは {{domxref("Document.stylesheets")}} を使って得られ、これは {{domxref("CSSStyleSheet")}} オブジェクトを含む配列のようなオブジェクトを返します。そうしたらお望みのままにスタイルを追加したり削除したりできます。ですがこのやり方について詳しくはやりません。なぜならスタイルをいじるにはちょっとばかり古風で難しいやり方だからです。もっと簡単なやり方があります。
まずは、動的にスタイルを指定したい要素に、インラインスタイルを直接追加するやり方です。これには {{domxref("HTMLElement.style")}} プロパティを使い、このプロパティはドキュメント中の各素要のインラインスタイル情報を保持しています。このオブジェクトのプロパティを更新すれば要素のスタイルを直接変更できます。
para.style.color = 'white'; para.style.backgroundColor = 'black'; para.style.padding = '10px'; para.style.width = '250px'; para.style.textAlign = 'center';
<p style="color: white; background-color: black; padding: 10px; width: 250px; text-align: center;">We hope you enjoyed the ride.</p>
注記: CSS ではハイフン記法になっているものを、JavaScript プロパティ版の CSS スタイルはどんな風に小文字のキャメルケースで書いている(background-color
と backgroundColor
とか)か見ておいて下さい。まぜこぜにしないよう注意して下さい、さもないと動きませんよ。
ドキュメントのスタイルを動的にいじる際によく使われる別のやり方をこれから見ていきましょう。
<style> .highlight { color: white; background-color: black; padding: 10px; width: 250px; text-align: center; } </style>
para.setAttribute('class', 'highlight');
どうやるかはあなた次第です。それぞれに利点と欠点があります。最初のやり方は少ない設定ですみ、簡単な場合には向いていますが、二つ目のやり方はずっときれいです (よくないやり方とされる、CSS と JavaScript の混在やインラインスタイルの使用がありません)。もっと大規模で複雑なアプリを作り始めたら、多分二つ目のやり方をよく使うようになると思いますが、結局はホントにあなた次第です。
ここまで、実はそれほど役に立つことをやってません! 静的なコンテンツの作成に JavaScript を使う利点はありません — JavaScript など使わず、普通に HTML に書けば良いんです。HTML よりややこしいですし、コンテンツを JavaScript で作成するのは他にも問題があります (検索エンジンで読めない、とか)。
次の二つのセクションでは、DOM API のもっと実践的な使い方を見ていきます。
注記: 私たちによる dom-example.htm l完成版 のデモが GitHub にあります (ライブ実行もどうぞー)。
ここまででは文書を操作するための {{domxref("Node")}} と {{domxref("Document")}} の機能ばかり見てきましたが、他のソースからデータを取ってきてあなたの UI で使ったって勿論かまわないわけです。あなたはデータが正しい形式である事を確認するだけです。これは JavaScript が弱い型付け言語であるために、他の多く言語の場合よりも簡単です — 例えば画面に表示しようとしたとき、数値は自動的に文字列に変換されます。
ここの例題ではよくある問題を解決していきます — あなたのアプリを表示しているウィンドウがどんな大きさであれ、それを同じ大きさになるようにすることです。これはゲームのような、表示する画面領域をできるだけ大きくしたいような場合に、しばしば役に立ちます。
まずは window-resize-example.html と bgtile.png ファイルのローカルコピーを作成して下さい。読み込んで見てみて下さい — 背景に画像がタイル表示された、{{htmlelement("div")}} 要素が画面に小さく表示されているでしょう。この領域が、私たちのアプリの UI 領域だとしていきます。
const div = document.querySelector('div'); let winWidth = window.innerWidth; let winHeight = window.innerHeight;
div.style.width = winWidth + 'px'; div.style.height = winHeight + 'px';
window.onresize = function() { winWidth = window.innerWidth; winHeight = window.innerHeight; div.style.width = winWidth + 'px'; div.style.height = winHeight + 'px'; }
注記: もし行き詰まったら、私たちによる 完成版ウィンドウリサイズ例題 (ライブ実行版もあるよ) を見て下さい。
この記事の締めとして、あなたにちょっとした難題を出したいと思います — 単純な買い物リストの例を作ってもらいます。フォーム入力(input)とボタンからリストに動的に商品を追加できるようにします。input に商品を入力してボタンを押したら:
完成版のデモはこんな感じになるでしょう:
この課題を完了させるには、以下のステップに従い、上で説明した通りに買い物リストが動くようにして下さい。
''
)を代入して、input 要素を空にします。focus()
メソッドを使って input 要素にフォーカスし、次の買い物リスト商品をすぐに入力できるようにします。注記: 本当にどうしようもなく詰まったら、私たちの 完成版買い物リスト (ライブ実行版もあるよ)を見て下さい。
私たちのドキュメントと DOM 操作に関する学習はこれで終わりです。ここまでくれば、ドキュメントの制御やユーザのウェブ体験に関するブラウザーの重要な部品は何か、理解できたと思います。一番大事な DOM とは何か、役に立つ機能を作るのにこれをどう使えば良いのか理解できたと思います。
ドキュメントをいじるのに役立つ機能はたくさんあります。私たちのリファレンスも見て、いろいろ発見して下さい:
(私共の Web API index から、MDNにあるウェブAPIに関する全ドキュメント一覧も見て下さい!)