以下は HTML 限定の話とする(XML/XHTML は考えない、つまり IE の document.selectNodes() を使わない)。
>>0
> IMG要素も一緒くたにループ処理にいれてしまう
そのための DOM2 Traversal。
// Gecko、Opera、Safari
/*
if (document.implementation &&
document.implementation.hasFeature ('Traversal', '2.0'))
*/
{
var node, tw = document.createTreeWalker (
document.getElementById ('foo'),
NodeFilter.SHOW_ELEMENT,
function (n) {
switch (n.tagName) {
case 'SPAN' :
case 'IMG' :
return NodeFilter.FILTER_ACCEPT;
dfault :
return NodeFilter.FILTER_SKIP;
}
},
false
);
while (node = tw.nextNode ()) {
node; // *[@id="foo"] 要素内の span/img 要素
}
node = tw = null;
}
もしノード数が多ければ、DOM3 XPath が圧倒的に速い。
// Gecko、Opera
/*
if (document.implementation &&
document.implementation.hasFeature ('XPath', '3.0'))
*/
{
var node, result = document.evaluate (
'descendant::*[ self::SPAN or self::IMG ]',
document.getElementById ('foo'),
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
for (var i = 0; i < result.snapshotLength; i++) {
node = result.snapshotItem (i); // *[@id="foo"] 要素内の span/img 要素
}
node = result = null;
}
IE を考慮するなら >>1 のように DOM1 Core の範囲内でやるしかない(TreeWalker のエミュレーション自体は割と簡単にできるが、遅い)。
>>1
> 配列みたいにconcatしたりsliceしたり出来たら良いな
NodeList は、文書ツリーに対する修正の影響を即座に受けるインタフェース(たとえば、文書ツリーからノードが除去されたら、NodeList からも除去される)。
単に配列として扱いたいだけならば、Array に移し替えた方が良い。JavaScript 1.6 の Array.map を使えば簡単。
<script type="application/javascript; version=1.6">
var callback = function (n) { return n; };
// span 要素と img 要素のリストを Array で作成
var nodeArray = Array.map (document.getElementsByTagName ('span'), callback);
nodeArray.push.apply (
nodeArray,
Array.map (document.getElementsByTagName ('img'), callback)
);
</script>
基本的にループでコピーするだけだから、IE でも(効率を気にしなければ)すぐできる。