JavaScriptの動かないコード (中級編) p要素への appendChild() で失敗する
クイズ…下記のJavaScriptコードが,意図した動作をしないのはどうしてですか。(制限時間1分)
やりたい事:
<p>タグの中に,div要素が1つ入っている。もう一つdiv要素を追加して,
<p id="target_tag"> <div id="div_1">1つ目のdivです。</div> <div id="div_2">2つ目のdivです。</div> </p>
というタグ構造にしたい。
<body> <script language="JavaScript"> function f() { // <div> タグを複製します。 var element_div2 = div_1.cloneNode(false); element_div2.id = "div_2"; element_div2.innerHTML = "2つ目のdivです。"; // 上の要素を,<p> タグの中に追加します。 target_tag.appendChild( element_div2 ); //alert(document.body.innerHTML); } </script> <input type="button" onClick="f()" value="クリックして要素を追加" /> <p id="target_tag"><div id="div_1">1つ目のdivです。</div></p> </body>
発生する不具合と原因
p要素の中に,div要素を入れることはできない。
HTMLタグには,
- ブロックレベル要素(特徴:「前後に改行を伴う」「四角で囲まれる」等)
- インライン要素(特徴:文字列を装飾する等)
の2種類がある。
pもdivもブロック要素である。
divのような大抵のブロック要素には,ブロック要素も,インライン要素も入れ子で挿入できる。
しかし,pはブロック要素であるにも関わらず,子ノードとしてインライン要素しか持つことができない。(これはHTMLの決まりである。)
参照:ブロック要素とインライン要素
http://www.tagindex.com/html_tag/basi...
つまり,
<div><p></p></div> とか <div><div></div></div>
は,正しいHTMLだが,
<p><div></div></p>
は,無効なHTMLである。
冒頭のスクリプトを実行してから,body.innerHTMLを表示させてDOM構造を確かめると,
Firefoxでは
<p id="target_tag"> <div id="div_2">2つ目のdivです。</div> </p> <div id="div_1">1つ目のdivです。</div><p></p>
のようになる。つまり,タグの入れ子構造を保ちつつも,不思議な入れ替わり現象が起きる。
IEでは
<p id="target_tag"> <div id="div_2">2つ目のdivです。</div> <div id="div_1">1つ目のdivです。</div> <p></p>
となり,タグの入れ子構造が崩壊する。
両者とも,画面での見かけ上は,いちおうdivタグの中身の文言が表示される。DOMアクセスを試みた段階で初めてエラーに気づくかもしれない。