题外话:这问题遇到好多遍,每次都不记得怎么解决,这次写下来好好提醒自己。

一、问题的出现

  在写原生Javascript时,我们会经常使用getElementsByTagName()和childNodes来实现对节点的遍历,但是getElementsByTagName()对复杂的DOM结构遍历明显不如用childNodes,因为childNodes能更好的处理DOM的层次结构。

  但是在跨浏览器开发中,问题就出现了:

<html>
<head></head>

<body onload="check();">

   <!--第一个要遍历的div,节点之间留有空格和回车-->
    <div id="firDiv">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    </div>

    <!--第二个要遍历的div,节点间无空格回车-->
    <div id="secDiv"><div>first</div><div>second</div><div>third</div></div>

    <script type="text/javascript">
        function check(){
            var childs1=$('firDiv').childNodes;
            var childs2=$('secDiv').childNodes;  
        
            alert("length of First Div: "+childs1.length+" , length of Second Div: "+childs2.length);
    }

        var $=function(id){ 
            return document.getElementById(id);
        }
    </script>
</body>
</html>

亲测后发现,用IE运行的结果是是3,3,而用Firefox、Chrome、Safari和Opera运行的结果则是7,3。

咦,怎么会有这种情况?

 

二、问题的根源

在结构上,div1和div2不同的地方在于,div1的子节点间有回车或者空格,而对象2则是一行写到尾。

造成不一致的原因就在于这:

IE是将一个完整标签作为一个节点。

而Firefox等浏览器除了上述的的情况外,也把一个标签的结束符“>”到下一个标签的起始符“<”之间的内容(除注释外,包括任何的文字、空格、回车、制表符)也算是一个节点,而且这种节点也有它们自己独特的属性和值:nodeName="#text"。

 

三、解决方法

在非IE内核的浏览器上使用childNodes遍历子节点时,将这些多余的节点过滤掉即可。

比如在for循环里加上:

if(childNode.nodeName=="#text") continue;

(或者是检测节点的类型)

这样便跳过这些多余的节点,使程序运行的更有效率。

posted on 2013-05-08 11:47  KwanChiLeung  阅读(914)  评论(1编辑  收藏  举报