| |
スクリプト作成技術の重要な要素の1つに、
HTML の読み込みが完了した後に HTML の追加・変更を行うものがあります。
この手法は NN4 なら document.write、IE なら insertAdjacentHTML等の
メソッドを使用しますが、Mozilla では使用できません。
そこで、今回は onLoad イベント以降に HTML の一部を変更する方法についての話題です。
Mozilla では onLoadイベント以降に HTML の一部を追加・変更する方法は開発時の経緯もあり、 実は複数の方法があります。
それぞれの方法について簡単に紹介していきましょう。
◆ W3C DOM2 な方法
W3C DOM2(Core)では HTML を追加するのに createElement や
createTextNode などの専用メソッドで DOMオブジェクトを生成し、
insertBefore や appendChild メソッドで追加や挿入することになっています。
つまり、HTML の最後に
'<p class="welcome">Hello Mozilla!</p>'
という HTML を追加しよとする場合は以下のようにします。
// <p class="welcome"></p> を作成 var pElement = document.createElement('P'); pElement.setAttribute('class','welcome'); // 'Hello Mozilla!' を追加 var text = document.createTextNode('Hello Mozilla!'); pElement.appendChild(text); // <p class="welcome">Hello Mozilla!</p> を BODYの最後に追加 document.body.appendChild(pElement);
この方法は論理的に理にかなったものですが、
今までの document.write や insertAdjacentHTML 等と異なり、
出力する HTML の DOM構造を強く意識しなければなりません。
HTML構文上のバグは作り込みにくい反面汎用的なスクリプトにはなりにくい欠点があります。
◆ Range Model の拡張機能を利用する方法
W3C DOM の Range Model は階層的に構築された DOM を文脈に沿って選択するためのモデルで、 ある特定の位置から別の位置までに含まれる部分のHTML を示すためのものです。
Mozilla ではこの Range モデルに NSRange という固有のクラスを
追加して createContextualFragment を始めとする、
一連のメソッドを追加することで選択操作と逆の操作を可能にしています。
つまり、HTML の最後に
'<p class="welcome">Hello Mozilla!</p>'
というHTML を追加しよとする場合は以下のようにします。
// 空の range オブジェクトを生成する var range = document.createRange(); range.selectNodeContents(document.body); range.collapse(true); // 挿入したい HTML からオブジェクトツリーを構築する var cf = range.createContextualFragment('<p>Hello Mozilla!<\/p>'); // 構築したオブジェクトツリーを BODYの最後に追加 document.body.appendChild(cf);
この方法は、W3C DOM2 な方法とは異なり DOM構造を強く意識する必要がないのですが、 非標準なのが難点です。
◆ IE 互換のためのメソッドを利用する方法
この方法は前項の createContextualFragment と setter/getter構文を組み合わせて、 IE の innerHTMLプロパティのエミュレーションをしたのがきっかけで Mozilla に採用されたものです。
※ 現在では setter/getter構文は削除されています
つまり、HTML の最後に '<p class="welcome">Hello Mozilla!</p>'
という
HTML を追加しよとする場合は以下のようにします。
document.body.innerHTML+='Hello Mozilla!<\/p>';
この方法は、Range Model の拡張機能を使用する方法と同様DOM構造を意識する必要がなく、 しかも IE と共通化できるのがメリットですが、 残念ながら insertAdjacentHTML のメソッドはありません。
# まあ、自分で定義することはできますがね。 f(^^;
結局、現在の Mozillaでは紹介した3つの方法がありますが、 いずれの方法を採ったらよいでしょうか?
W3C DOM2 な方法以外は現在の仕様にはありませんので、
純粋に W3C DOM に準拠したスクリプトを組むなら「W3C DOM2 な方法」でしょう。
また、現在の W3C DOM2 HTML が Working Draft になっているため、
もしかすると innerHTML プロパティが HTMLElement に追加される可能性もあります。
便利さの点では NSRange または innerHTML を使用する方法が楽で、汎用的な
スクリプトも組みやすいのですが、HTML を解釈する分実行スピードも落ちます。
また、Mozillaの正版でこれらのメソッドが廃棄または変更される可能性もあります。
ってことで、そのヘンを踏まえた上で好きに使っても良いような気もします(笑)。