Yso*_*oL8 5 html javascript debugging
我在Firefox中遇到了一个非常奇怪的错误.
我在外部文件中有一个javascript函数,可以在常规复杂网站上完美运行.然而,我一直在组织一些示例,并遇到一些奇怪的事情.
使用html格式化(在编辑器中):
<div><p>Q: Where's the rabbit?</p><p class="faq_answer">A: I don't know, honest</p></div>
Run Code Online (Sandbox Code Playgroud)
Javascript按预期工作.
但是当这样的时候:
<div>
<p>Q: Where's the rabbit?</p>
<p class="faq_answer">A: I don't know, honest</p>
</div>
Run Code Online (Sandbox Code Playgroud)
它失败了:
elementsList[i].parentNode.firstChild.appendChild(finalRender.cloneNode(true));
Run Code Online (Sandbox Code Playgroud)
为什么在地球上格式化html会导致什么呢?
这不是一个bug.DOM不仅有元素节点,还有文本节点 [docs](等等).在这个例子中:
<div>
<p>Q: Where's the rabbit?</p>
Run Code Online (Sandbox Code Playgroud)
你至少有两个文本节点:
<div>和之间<p>,包含一个换行符.<p>元素节点内的一个文本节点,包含文本Where's the rabbit?.因此,如果elementsList[i].parentNode指的是<div>元素,
elementsList[i].parentNode.firstChild
Run Code Online (Sandbox Code Playgroud)
将引用第一个文本节点.
如果要获取第一个元素节点,请使用
elementsList[i].parentNode.children[0]
Run Code Online (Sandbox Code Playgroud)
更新:您提到了Firefox 3.0,实际上,此版本不支持该children属性.
Afaik唯一的解决方案是遍历子节点(或遍历它们)并测试它是否是文本节点:
var firstChild = elementsList[i].parentNode.firstChild;
// a somehow shorthand loop
while(firstChild.nodeType !== 1 && (firstChild = firstChild.nextSibling));
if(firstChild) {
// exists and found
}
Run Code Online (Sandbox Code Playgroud)
你可能想把它放在一个额外的功能:
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;
}
Run Code Online (Sandbox Code Playgroud)
您可以(也应该)考虑使用从所有这些中抽象出来的库,比如jQuery.
这取决于你的代码实际在做什么,但如果你为每个节点运行这个方法,它将是这样的:
$('.faq_answer').prev().append(finalRender.cloneNode(true));
Run Code Online (Sandbox Code Playgroud)
(假设p元素总是在.faq_answer元素之前)
这是整个代码,您不必再循环遍历元素.