我有一个很好的解决方案,可以从HTML节点树中获取HTML注释
var findComments = function(el) {
var arr = [];
for (var i = 0; i < el.childNodes.length; i++) {
var node = el.childNodes[i];
if (node.nodeType === 8) {
arr.push(node);
} else {
arr.push.apply(arr, findComments(node));
}
}
return arr;
};
var commentNodes = findComments(document);
// whatever you were going to do with the comment...
console.log(commentNodes[0].nodeValue);
来自this thread。 我所做的一切只是添加了这个小循环以打印出所有节点。
var arr = [];
var findComments = function(el) {
for (var i = 0; i < el.childNodes.length; i++) {
var node = el.childNodes[i];
if (node.nodeType === 8) {
arr.push(node);
} else {
arr.push.apply(arr, findComments(node));
}
}
return arr;
};
var commentNodes = findComments(document);
//I added this
for (var counter = arr.length; counter > 0; counter--) {
console.log(commentNodes[counter].nodeValue);
}
我不断收到此错误消息:
RangeError:为函数调用调试器提供了太多参数 评估代码:9:13
编辑:我在粘贴时遇到错字,将代码从i--更改为counter-
答案 0 :(得分:1)
由于数组从索引0开始,实际上数组的最后一项是arr.length - 1
。
您可以通过以下方式修复它:
for (var counter = arr.length - 1; counter >= 0; counter--)
注意,我添加了arr.length -1
和counter >= 0
,因为零是数组的第一个索引。
答案 1 :(得分:1)
有关使用apply
合并数组的信息,请参见此评论in MDN docs:
如果第二个数组(示例中为moreVegs)非常大,则不要使用此方法,因为实际上一个函数可以使用的最大参数数量是有限的。有关更多详细信息,请参见apply()。
apply page中的另一条注释:
但是要注意:以这种方式使用应用时,存在冒超出JavaScript引擎参数长度限制的风险。应用带有太多参数(想想成千上万个参数)的函数的结果因引擎而异(JavaScriptCore的硬编码参数限制为65536),因为该限制(甚至包括任何过大堆栈的性质)行为)未指定。一些引擎将引发异常。更有害的是,其他人将任意地限制实际传递给应用函数的参数数量。为了说明后一种情况:如果这样的引擎有四个参数的限制(实际上的限制当然要高得多),则好像在上面的示例中通过了参数5、6、2、3一样,而不是整个数组。
答案 2 :(得分:0)
添加for
循环并不是您唯一更改的内容(并且也可以查看有关修复该循环的其他答案)。您还将arr
的声明从函数的内部移到了外部,使arr
相对全局。
因此,对findComments()
的每个递归调用都在相同数组上进行,并且.apply()
调用每次都将整个内容推回到数组的末尾。一段时间后,其长度超过了运行时的限制。
问题顶部发布的原始函数在函数内部声明了arr
。因此,每个递归调用都有其自己的本地数组。在具有很多个注释节点的文档中,它仍然可能会出现“范围错误”。