我有一段Javascript代码,用于查找DOM中的单个表,然后尝试操纵其第一个子项thead
(实际上,它会迭代该子项的子项tr
条目,但这对问题并不重要)。执行此操作的代码是:
var tableNode = document.getElementById("table").firstChild;
这在Firefox ESR(10/17/24)和IE9中运行良好但在IE10中失败,原因似乎是因为IE10正在插入奇怪的DOM条目,而且它是我正在接受{{1而不是所需的firstChild
。我将此基于以下DOM转储以及thead
设置为字符串类型的事实。
IE10兼容模式下的DOM(它也可以工作)看起来像这样:
你可以看到DOM确实看起来很合理。但是,在正常IE10模式下检查DOM会显示:
对于它的价值,Chrome给了我:
和FF17esr给了我:
它们似乎都没有空的文本元素。
现在,我可以在兼容模式下运行该网站,但要告诉所有客户,这是一件烦人的事情。我还可以添加丑陋的东西:
tableNode.data
到我的输出,但我不完全确定可能有什么其他影响。
我想先了解为什么 IE10正在添加这些节点,而IE9 / FF / IE10compat则没有。我发现有一些讨论说HTML中的空格可能会导致它,但在我看来,这不应该导致创建随机节点,无论如何,我不认为我有任何多余的空白区域。虽然我应该提到上面提到的<meta http-equiv="X-UA-Compatible" content="IE=9">
作为类型字符串的值实际上是tableNode.data
,这意味着该行末尾的换行符可能正在创建此DOM条目。
\n
会导致三个 DOM条目,<tag>line 1</tag>
<tag>line 2</tag>
,tag
和empty node
只是因为它们之间有换行符。
关于如何最好地解决这个问题的任何想法?我是否必须修改我的Javascript代码才能跳过这些DOM条目?
答案 0 :(得分:1)
您永远无法知道浏览器在何处插入文本节点,因此您必须确保在浏览器将文本节点放在那里时获得第一个子元素。
这是一个简单的功能:
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;
}
或者,如果您只想获得<thead>
元素,可以直接使用:
table.getElementsByTagName("thead")[0]
答案 1 :(得分:1)
你绝对相信Firefox不会显示那些空文本节点吗?我问是因为它应该,如果没有,那么它就是Firefox中的一个错误。
以前只有IE的行为符合您的预期。所有其他浏览器,包括Firefox,Chrome,Safari和Opera都遵循W3C DOM标准,这要求他们保留这些空白。 IE10现在加入了其他Web浏览器的行列,并以符合标准的方式运行。
你是正确的抱怨这没有意义,但这是标准所要求的。
因此,获取元素的正确方法是检查它是tagName
:
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>
在除旧版IE之外的所有浏览器中,上面的页面都会输出:
undefined
bar
那是因为firstChild
是空文本节点。如果您想查看console.log
。
firstChild