0

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

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

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

IE10 兼容模式下的 DOM(也适用)如下所示:

在此处输入图像描述

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

在此处输入图像描述

对于它的价值,Chrome 给了我:

在此处输入图像描述

FF17esr 给了我:

在此处输入图像描述

两者似乎都没有空文本元素。

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

<meta http-equiv="X-UA-Compatible" content="IE=9">

到我的输出,但我不完全确定可能有什么其他影响。

我想首先了解为什么IE10 会添加这些节点,而 IE9/FF/IE10compat 却没有。我发现有一些讨论表明 HTML 中的空格可能是导致它的原因,但在我看来,这不应该导致创建随机节点,而且无论如何,我认为我没有任何多余的白色空间。虽然我应该提到上面提到的字符串类型的值实际上tableNode.data\n,这意味着行尾的换行符可能正在创建这个 DOM 条目。

但是,老实说,这似乎很荒谬。据我所知,HTML 应该忽略标签之外的空格,或者至少将其折叠成一个元素。我很难相信这样的事情:

<tag>line 1</tag>
<tag>line 2</tag>

会产生三个DOM 条目,,tag只是因为它们之间有一个换行符。empty nodetag

关于如何最好地解决这个问题的任何想法?我是否必须修改我的 Javascript 代码才能跳过这些 DOM 条目?

4

2 回答 2

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]
于 2013-10-25T03:54:22.320 回答
1

您确定 Firefox 不会显示那些空文本节点吗?我问是因为它应该,如果不是,那么它是 Firefox 中的一个错误。

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

您可以抱怨这没有意义,但这是标准所要求的。

因此,获取元素的正确方法是检查它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

于 2013-10-25T03:55:20.953 回答