【问题标题】:IE10 inserting blank text DOM entriesIE10 插入空白文本 DOM 条目
【发布时间】:2013-10-25 03:39:09
【问题描述】:

我有一段 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">

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

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

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

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

将导致 三个 DOM 条目,tagempty nodetag,只是因为它们之间有一个换行符。

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

【问题讨论】:

  • 我的回答中描述了解决此问题的方法。像 jQuery 和 YUI 这样的库以类似的方式解决它。除 IE9 及以下的所有浏览器都执行此操作。不要看 DOM 检查器,用 javascript 代码测试它。有关可以在各种浏览器上运行的测试 HTML 文件,请参阅我的答案。

标签: javascript dom internet-explorer-10


【解决方案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;
}

或者,如果您只想获取&lt;thead&gt; 元素,您可以简单地使用:

table.getElementsByTagName("thead")[0]

【讨论】:

【解决方案2】:

您确定 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 是空文本节点。如果您想查看firstChild,可以console.log

【讨论】:

  • 或者按照 jfriend00 的建议去做,并检查它是标签而不是文本节点或评论(是的,DOM 保留了标准要求的 cmets,是的,以前版本的 IE 有时没有不要这样做)
  • 我已经从 Chrome 和 FF17esr 添加了 DOM 转储。它们似乎都没有保留空白元素。你确定这是标准要求的吗?
  • 虽然在 OP 的情况下它仍然很奇怪,因为&lt;table&gt;/&lt;tr&gt;/etc..Not allowed elements (including actual text) would generally rendered outside &lt;table&gt; 中允许的元素太多了。评论可能很特别,但通常你知道有评论,但换行和空格或多或少会欺骗。
  • FF 和 Chrome 中的 DOM 浏览器不显示空格。但如果你通过 javascript 访问它,它就在 DOM 中。
  • @Passerby:啊,表格的情况可能是独一无二的,因为某些浏览器选择在表格之外呈现空白。但一般情况仍然是正确的:空白被保留为文本节点。
猜你喜欢
  • 2018-02-28
  • 2013-02-27
  • 2021-09-23
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多