5

我正在编写一个 Chrome 扩展程序,它将搜索 DOM 并突出显示页面上的所有电子邮件地址。我发现这是在页面上查找符号,但它只在有一个电子邮件地址时正确返回,当找到多个地址时它会中断。

found = document.evaluate('//*[contains(text(),"@")]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);

如果找到多个返回倍数的正确方法是什么?

4

1 回答 1

6

如果要处理多个结果,请不要调用.snapshotItem(0)document.evaluate()而是使用for循环和循环遍历结果snapshotLength()

snapshotLength()示例:使用with遍历结果snapshotItem()

var nodesSnapshot = document.evaluate('//*[contains(text(),"@")]',
    document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );

for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
{
  console.dir( nodesSnapshot.snapshotItem(i) );
}

要么,要么指定XPathResult.UNORDERED_NODE_ITERATOR_TYPE参数(而不是XPathResult.ORDERED_NODE_SNAPSHOT_TYPE),并使用while循环iterateNext()

示例:使用迭代结果iterateNext()

var iterator = document.evaluate('//*[contains(text(),"@")]',
    document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );

try {
  var thisNode = iterator.iterateNext(); 
  while (thisNode) {
    console.dir( thisNode );
    thisNode = iterator.iterateNext();
  } 
}
catch (e) {
  console.log( 'Error: Document tree modified during iteration ' + e );
}

在与此问题相反的情况下(当您确实只想获取第一个匹配节点的情况下)您可以指定XPathResult.FIRST_ORDERED_NODE_TYPE值,仅返回一个节点,然后使用属性(而不是方法)singleNodeValue

示例:使用XPathResult.FIRST_ORDERED_NODE_TYPEsingleNodeValue

var firstMatchingNode = document.evaluate('// [contains(text(),"@")]',
    document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );

console.dir( firstMatchingNode.singleNodeValue );

取而代之的是获取文本或倒数,或测试真/假条件

请注意,在其他值(常量)中,您可以指定为倒数第二个参数以document.evaluate()获取其他结果类型,您可以使其直接返回:

  • XPathResult.STRING_TYPE从文档的某些部分中删除的单个字符串 ( )
  • 表示某种计数的数字 ( XPathResult.NUMBER_TYPE);例如,在文档中找到的电子邮件地址的计数
  • 一个布尔值 ( XPathResult.BOOLEAN_TYPE),表示文档的某些真/假方面;例如,文档是否包含任何电子邮件地址的指示符

当然,要返回那些其他结果类型,作为第一个参数提供的 XPath 表达式document.evaluate()需要是一个表达式,该表达式实际上将返回一个字符串、一个数字或一个布尔值(而不是返回一组属性节点或元素节点)。


更多在 MDN

上面的例子都是基于 MDN Introduction to using XPath in JavaScript tutorial,强烈推荐给任何尝试使用 XPath 和document.evaluate().

于 2015-09-08T22:35:13.480 回答