Javascript IE10插入空白文本DOM条目

Javascript IE10插入空白文本DOM条目,javascript,dom,internet-explorer-10,Javascript,Dom,Internet Explorer 10,我有一段Javascript代码,它在DOM中定位单个表,然后尝试操作它的第一个子项thead(实际上,它迭代该子项的子项tr,但这对问题并不重要)。执行此操作的代码是: var tableNode = document.getElementById("table").firstChild; 这在Firefox ESR(10/17/24)和IE9中运行良好,但在IE10中失败,原因似乎是IE10插入了奇怪的DOM条目,这是我使用的firstChild而不是所需的thead。我基于下面的DOM转

我有一段Javascript代码,它在DOM中定位单个表,然后尝试操作它的第一个子项
thead
(实际上,它迭代该子项的子项
tr
,但这对问题并不重要)。执行此操作的代码是:

var tableNode = document.getElementById("table").firstChild;
这在Firefox ESR(10/17/24)和IE9中运行良好,但在IE10中失败,原因似乎是IE10插入了奇怪的DOM条目,这是我使用的
firstChild
而不是所需的
thead
。我基于下面的DOM转储以及
tableNode.data
被设置为字符串类型这一事实

IE10兼容模式下的DOM(它也可以工作)如下所示:

您可以看到DOM看起来确实是合理的。但是,在正常IE10模式下检查DOM会显示:

Chrome为我提供了:

FF17esr给了我:

它们似乎都没有空文本元素

现在,我可以在兼容模式下运行该网站,但这是一件烦人的事情,必须告诉我们所有的客户。我显然还可以加上一句可怕的话:

<meta http-equiv="X-UA-Compatible" content="IE=9">
将导致三个DOM条目,
tag
空节点
tag
,因为它们之间有一个换行符


关于如何最好地解决这个问题,有什么想法吗?我是否必须修改Javascript代码以跳过这些DOM条目?

您永远不知道浏览器可能在哪里插入文本节点,因此您必须确保获得第一个子“元素”,以防浏览器将文本节点放在那里

下面是一个简单的函数:

getFirstChildElement(parent) {
    var node = parent.firstChild;
    // advance until we get to an element node (skipping text and comment nodes)
    while (node && node.nodeType !== 1) {
        node = node.nextSibling;
    }
    return node;
}
或者,如果您只想获取
元素,您可以简单地使用:

table.getElementsByTagName("thead")[0]

你绝对确定Firefox不会显示那些空文本节点吗?我这样问是因为它应该,如果它没有,那么它就是Firefox中的一个bug

以前只有IE的行为符合你的预期。包括Firefox、Chrome、Safari和Opera在内的所有其他浏览器都遵循W3CDOM标准,该标准要求它们保留这些空白。IE10现在加入了其他网络浏览器的行列,并以符合标准的方式运行

你可以抱怨这毫无意义,但这正是标准所要求的

因此,获取元素的正确方法是检查它的
标记名

var table = document.getElementById("table");
var child = table.firstChild;

while (child && child.tagName != 'thread') {
    child = child.nextSibling;
}

// remember to check child after this point because it may be undefined

补充说明 Firebug和Chrome的DOM浏览器为了方便起见隐藏了这些文本元素,但它仍然存在。您可以尝试以下方法:

<html>
<body>
    <div id="foo">
        <div id="bar">
        </div>
    </div>
    <script>
        var f = document.getElementById('foo');
        document.body.innerHTML += f.firstChild.id + <br>;
        document.body.innerHTML += f.firstChild.nextSibling.id + <br>;
    </script>
</body>
</html>

这是因为
firstChild
是空文本节点。如果您想查看
firstChild

的话,您可以
console.log
it,或者按照jfriend00的建议,检查它是一个标记,而不是一个文本节点或注释(是的,DOM保留了标准要求的注释,是的,IE的早期版本有时没有这样做)我已经从Chrome和FF17esr添加了DOM转储。它们似乎都没有保留空格元素。你确定这是标准所要求的吗?虽然在OP的例子中它仍然很奇怪,因为里面只允许有那么多元素。注释可能是特殊的,但通常你知道有注释,但是换行符和空格或多或少都是骗人的。FF和Chrome中的DOM浏览器不显示空格。但是,如果您通过javascript访问它,它就在DOM中。@Passerby:啊,表的大小写可能是唯一的,因为有些浏览器选择在表外呈现空白。但一般情况仍然是这样的:空白保留为文本节点。while语句中的
1
是什么?@paxdiablo-您可以在此处看到各种节点类型值:<代码>1是一个元素节点。我的答案中描述了解决此问题的方法。像jQuery和YUI这样的库以类似的方式解决它。除IE9及以下版本外,所有浏览器都会这样做。不要看DOM检查器,用javascript代码测试它。有关可以在各种浏览器上运行的测试HTML文件,请参见我的答案。
<html>
<body>
    <div id="foo">
        <div id="bar">
        </div>
    </div>
    <script>
        var f = document.getElementById('foo');
        document.body.innerHTML += f.firstChild.id + <br>;
        document.body.innerHTML += f.firstChild.nextSibling.id + <br>;
    </script>
</body>
</html>
undefined
bar