JavaScriptの技法:DOM操作の落とし穴とその回避方法

文:Nick Gibson(Builder AU)
翻訳校正:原井彰弘
2008/01/11 12:00

JavaScriptでDOMを操作するのはAjaxアプリケーションでよく使われる。しかし、JavaScriptによるDOM探索は手間がかかり、落とし穴もある。ここではその回避方法を探ってみよう。

 この問題は、DOMの出力を2つのパスに分割することで解決できる。まず、最初のパスではデータを一時的に配列へ格納し、続いて、配列の各要素をドキュメントに出力するのである。

function traverseDOM(x, arr) {
        arr.push(x);
        for (var i = 0; i < x.childNodes.length; i++) {
                traverseDOM(x.childNodes[i], arr);
        }
        return arr;
}

function printDOM(x) {
        arr = Array();
        arr = traverseDOM(x, arr);
        for (var i = 0; i < arr.length; i++) {
                document.write(arr[i]);
        }
}

 このコードを実行すると、以下のような出力が得られる。

[object HTMLDocument][object HTMLHtmlElement][object HTMLHeadElement][object HTMLScriptElement][object Text][object HTMLTitleElement][object Text][object HTMLBodyElement][object Text][object HTMLParagraphElement][object Text][object Text][object HTMLParagraphElement]http://builderau.com.au/[object Text][object Text]

 ところで、この出力も問題だ。すべてが混ざり合っており、どのタグがどのタグの子要素なのかまったく見当がつかないのである。本来は、ツリーを出力する際に整形を行うタグを挿入するのが理想だ。たとえば、最初のパスで作成する配列を、それぞれのタグの子ノードに対応する形で複数階層にするという方法もある。しかし、それは出力に手間がかかりそうだ。そこで、ここではより簡単な方法を選択することにする。

 このコードでは出力をドキュメントに直接書き込んでいるので、ブラウザが持っている知識をうまく利用して、テキストに含まれているタグの解釈をブラウザに任せてしまうことを考える。つまり、ドキュメントにタグを書き込んだ際に、そのままタグをテキストで出力させるのではなく、ブラウザにタグを解釈させてしまうのである。

 以下の例では、最初のパスでdl要素(定義リストを表すタグ)を配列に加えることによって、最終的に表示されるドキュメントの整形を行っている。

function traverseDOM(x, arr) {
        arr.push("<DL><DT>")
        arr.push(x);
        for (var i = 0; i < x.childNodes.length; i++) {
                arr.push("<DD>");
                traverseDOM(x.childNodes[i], arr);
        }
        arr.push("</DL>");
        return arr;
}

function printDOM(x) {
        arr = Array();
        arr = traverseDOM(x, arr);
        for (var i = 0; i < arr.length; i++) {
                document.write(arr[i]);
        }
}
記事の感想やご意見をコメントでお寄せください(CNET_IDログインが必要です)
ログイン パスワードを忘れた方  |  新規登録
  • 新着記事
  • 人気記事
  • 特集
  • ブログ
  • 読者投票
    いよいよ7月11日に売り出される「iPhone 3G」。今のところの購入予定は?

    投票受付期間:2008年7月7日 〜 2008年7月11日
  • » 投票しないで結果だけ見る