由html空格引起的非常奇怪的错误

时间:2011-07-04 13:51:43

标签: javascript html debugging

我在Firefox中遇到了一个非常奇怪的错误。

我在外部文件中有一个javascript函数,可以在常规复杂网站上完美运行。但是我一直在组织一些示例,并遇到了一些奇怪的事情。

使用html格式化(在编辑器中):

<div><p>Q: Where's the rabbit?</p><p class="faq_answer">A: I don't know, honest</p></div>

Javascript按预期工作。

但是这样的时候:

<div>
<p>Q: Where's the rabbit?</p>
<p class="faq_answer">A: I don't know, honest</p>
</div>

在这一行失败了:

elementsList[i].parentNode.firstChild.appendChild(finalRender.cloneNode(true));

为什么在地球上格式化html会导致什么呢?

3 个答案:

答案 0 :(得分:7)

这不是一个错误。 DOM不仅有元素节点,还有text nodes [docs](等等)。在这个例子中:

<div>
<p>Q: Where's the rabbit?</p>

您至少有两个文本节点:

  • <div><p>之间的一个,包含换行符
  • <p>元素节点内的一个文本节点,包含文本Where's the rabbit?

因此,如果elementsList[i].parentNode引用<div>元素,

elementsList[i].parentNode.firstChild

将引用第一个文本节点。

如果要获取第一个元素节点,请使用

elementsList[i].parentNode.children[0]

更新:您提到的是Firefox 3.0,的确是the children property is not supported in this version

Afaik唯一的解决方案是循环遍历子节点(或遍历它们)并测试它是否是文本节点:

var firstChild = elementsList[i].parentNode.firstChild;

// a somehow shorthand loop
while(firstChild.nodeType !== 1 && (firstChild = firstChild.nextSibling));

if(firstChild) {
    // exists and found
}

你可能想把它放在一个额外的功能中:

function getFirstElementChild(element) {
    var firstChild = null;
    if(element.children) {
        firstChild = element.children[0] || null;
    }
    else {
      firstChild = element.firstChild;
      while(firstChild.nodeType !== 1 && (firstChild = firstChild.nextSibling));
    }
    return firstChild;
}

您可以(也应该)考虑使用从所有内容中抽象出来的库,例如jQuery

这取决于你的代码实际上在做什么,但如果你为每个节点运行这个方法,它将是这样的:

$('.faq_answer').prev().append(finalRender.cloneNode(true));

(假设p元素始终位于.faq_answer元素之前)

这是整个代码,你不必再遍历元素了。

答案 1 :(得分:2)

因为您在<div><p>之间有一个文本节点。

像往常一样,浏览器错误的假设是错误的:相反,这是一个程序员错误!

答案 2 :(得分:0)

无法使用ParentNode.children来实现它吗?