我目前正在玩JS和嵌入式XPath。我正在尝试创建一个小测试脚本,并发现了一个我想要理解的有趣错误。我正在调用这样的evaluate函数:
var result = document.evaluate(
xpath,
document,
null,
XPathResult.ANY_TYPE);
在这种情况下,我的结果好坏参半。字符串,布尔值和数字类型没有问题要处理,但UNORDERED_NODE_ITERATOR_TYPE在某种程度上是棘手的。
我处理结果的功能如下:
function nodes(iterator, parentNode) {
var cur = iterator.iterateNext(); // do not touch! altering this object causes a INVALID_STATE_ERR Exception
var myObj = cur == null || cur == undefined ? undefined : cur.cloneNode(true);
var count = 0;
while(myObj) {
parentNode.appendChild(myObj);
var = iterator.iterateNext().cloneNode(true);
}
}
但是当我尝试运行此函数时,我得到一个INVALID_STATE_ERR异常。但为什么?我克隆了对象,我的父节点是一个新创建的元素节点。 (document.createElement('body')应该替换最后的原始主体节点。
我是否需要以另一种方式创建new-body元素?此异常是否被抛出,因为新的body元素已附加到当前文档树?如果我不能使用createElement,我怎么能这样做?
答案 0 :(得分:1)
我尝试制作一个测试用例来重现问题,http://jsfiddle.net/pe95g/2/。它适用于Mozilla和Opera,但在Chrome和Safari等WebKit浏览器中失败。在我看来它不应该失败,因为正在查询的DOM文档没有改变,只有在XPath迭代发生时才创建和更改未附加到该文档的节点。另一方面,W3C DOM Level 3 XPath注释对于“使迭代无效”的“文档修改”不是很精确。
作为一种解决方法,我尝试使用快照而不是使用DOM Level 3 XPath API http://jsfiddle.net/WT5Uk/1/的迭代器,这种方法适用于所有支持document.evaluate
的所有四个主要桌面浏览器(即Mozilla,Opera,Safari,Chrome)。这是我可以建议的唯一解决方法。