我在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会导致什么呢?
答案 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来实现它吗?