2008-07-10
NodeList型を知る
element.childNodesが返すやつ。こんなコードで知った。
var nodes = elem.childNodes;
for (var i=0; i<nodes.length; i++)
nodes[i].parentNode.removeChild(nodes[i]);
上のコードはエラーになるわけだけど、これはelem.childNodesの返す値を配列ノリで扱っているため。 実際に返ってくるのはこんな定義の値。(引用元)
interface NodeList {
Node item; // 0から始まる配列の添え字みたいの。
readonly attribute unsigned long length; // NodeListの長さ。読み取り専用。
};
NodeListの性質で、最初に掲示したようなやり方でitemを削除するとNodeList自体が縮まることになる (最初、 [elem, elem, elem, elem, elem] だったのが、 [elem, elem, elem, elem] となる)。 これを配列の感覚で扱うと、最初はnodes[4] でアクセスできたものが、削除後にアクセスするとundefinedを返す。
これに対処するやり方はいくつかあって、
// elem.firstChildをあるだけ削除
while (elem.firstChild) {
elem.removeChild(elem.firstChild)
}
// elem.lastChildをあるだけ削除
while (elem.lastChild) {
elem.removeChild(elem.lastChild)
}
// ダイレクトに
elem.innerHTML = "";
ただ、これだと「ある条件」を満たすエレメントだけを削除したい場合にどうしようもないので、
// 愚直に
var nodes = elem.childNodes;
for (var i=0, target=[]; i<nodes.length; i++)
if ( 削除条件 ) remove.push(nodes[i]);
for (var i=0; i<target.length; i++)
elem.removeChild(target[i]);
// ダイレクトに
elem.innerHTML = elem.innerHTML.replace(/削除条件/, "");
という風にすればOK。
というようなことを今日知りました。