このページで扱うのはDOM(Document Object Model)です。 DOMはdocumentの構造をオブジェクト指向的に扱うことが出来ます。
DOMに要素を加えてみましょう。
まずdocument.create~メソッドを使って要素を作ります。
createTextNodeは文字列一つを引数に取り、
html中の文字列を表すDOM要素を作ります。
appendChildはDOM要素一つを引数に取り、
親要素の末尾に引数の要素を追加します。
DOMを操作するにはbody要素が読み込み終わっている方が都合がよいので、
このページでは前段で扱った onload イベントを利用します。
(Hello, DOM! Sample 1)
<html>
<head>
<script type="text/javascript">
function init(){
document.body.appendChild(
document.createTextNode("Hello, DOM!"));
}
</script>
</head>
<body onload="init();">
</body>
</html>
Firefox でサンプルを開いて「 Hello, DOM!DOCTYPE 」を選択し、 「選択した部分のソースを表示」をしてみましょう。 body 要素に「 Hello, DOM!DOCTYPE 」が加えられているのが判ります。 このように「選択した部分のソースを表示」によって JavaScript で加工した後のソースを見ることが出来ます。 「表示 - ページのソース」や 何も選択しないで「ページのソースを表示」を行った際に 見られるソースは JavaScript で加工する前のものになります。 憶えておくとデバッグの際に役に立ちます。
続いて文書中のDOM要素を取り出す方法を見てみましょう。 getElementsByTagNameはその要素の子供以下にある要素の中から 引数で指定したタグで出来た要素を配列として取り出すメソッドです。 (Hello, DOM! Sample 2)
<html>
<head>
<script type="text/javascript">
alert(document.getElementsByTagName("head")[0].innerHTML);
</script>
</head>
</html>
ここでは
alert(document.getElementsByTagName("head")[0].innerHTML);
としてdocument中のhead要素を取り出しています。 head要素は通例一つしかないので [0] で最初のものを選びます。 innerHTML というプロパティはその要素の中身を html の断片の文字列として取り出すものです。
DOM Tree について説明します。 DOM は一つのオブジェクトが幾つかの子供オブジェクトをとる という組合せを再帰的に繰り返すことにより文書を作っています。
RootNode--+--Leaf
|
+--Node--+--Node
|
+--Node
というように図示される、 このデータ構造を Tree と呼びます。 ちなみに子供を持たない要素を Leaf 、 子供を持ちうる要素を Node と呼びます。 親を持たない(上の図では左端)要素を Root と呼びます。 もちろん Root は通例 Node です。
DOM では各 Node のプロパティ/メソッドを使って Tree を操作します。 Node の子供は childNodes プロパティにより Node の配列として取り出せます。 各 Node は nodeName, nodeValue プロパティから 基本的な特質が得られます。 サンプルは再帰的にサンプル自身の Node を表示します。 (Hello, DOM! Sample 4)
In Deep
それではソースに動的にscriptタグを書き込んだらどうなるでしょうか。 前段のソースを流用してイベントの順序を確定していきましょう。 (Hello, DOM! Sample 3)
<html>
<head>
<script type="text/javascript">
document.write("Hello, html/head/script 1!");
var script = document.createElement("script");
script.appendChild(
document.createTextNode("document.write('Hello, DOM/script!');"));
document.getElementsByTagName("head")[0].appendChild(script);
document.write("Hello, html/head/script 2!");
</script>
</head>
</html>
この場合、html/head/script 1 -> DOM/script -> html/head/script 2 という順番に実行されました。 html 本体の解釈が終わってから追加された要素を解釈するのではなく、 追加された瞬間にscript要素が評価されているようです。