在HTML页面中使用JavaScript查找单词

18

如何快速搜索HTML页面中的词汇?

如何获取包含该词汇的HTML标签?(这样我就可以处理整个标签了)

5个回答

23

要找到包含该单词的元素,您需要遍历整个树,在文本节点中查找并应用与上述相同的测试。一旦在文本节点中找到该单词,返回该节点的父级。

var word = "foo",
    queue = [document.body],
    curr
;
while (curr = queue.pop()) {
    if (!curr.textContent.match(word)) continue;
    for (var i = 0; i < curr.childNodes.length; ++i) {
        switch (curr.childNodes[i].nodeType) {
            case Node.TEXT_NODE : // 3
                if (curr.childNodes[i].textContent.match(word)) {
                    console.log("Found!");
                    console.log(curr);
                    // you might want to end your search here.
                }
                break;
            case Node.ELEMENT_NODE : // 1
                queue.push(curr.childNodes[i]);
                break;
        }
    }
}

这段代码在Firefox中可行,但对于IE则不保证。

它的作用是从body元素开始检查是否存在单词。如果不存在,则停止搜索;如果存在,则循环遍历body的所有直接子节点。如果找到文本节点,则检查该文本节点中是否包含该单词。如果找到一个元素,则将其推入队列中。一直重复以上操作,直到找到该单词或没有更多的元素需要搜索。


innerText 不包括任何标签名称,只包含文本节点的值,因此您可以放心使用。 - nickf
1
小提醒,@nickf:我觉得你忘记了innerText属性在FF和其他一些浏览器中不被支持。在这些情况下,你可能想用'textContent'来替代它。不过还是给个赞+1;-) - Cerebrus
是的,当我测试这段代码时发现了这一点。textContent 似乎以相同的方式工作。 - nickf

6

你可以遍历DOM元素,寻找其中的子字符串。虽然不够快速和优雅,但对于小型HTML可能足够使用。

我会尝试使用递归来实现,例如:(代码未经测试)

findText(node, text) {
  if(node.childNodes.length==0) {//leaf node
   if(node.textContent.indexOf(text)== -1) return [];
   return [node];
  }
  var matchingNodes = new Array();
  for(child in node.childNodes) {
    matchingNodes.concat(findText(child, text));
  }
  return matchingNodes;
}

1
你可以尝试使用XPath,它快速而准确。

http://www.w3schools.com/Xpath/xpath_examples.asp

如果XPath有点复杂,您可以尝试使用任何JavaScript库,如jQuery,它可以隐藏样板代码并使表达所需查找的内容更容易。

此外,从IE8和下一个Firefox 3.5开始,还实现了选择器API。您只需要使用CSS来表达要搜索的内容。


OP正在HTML内容中进行字符串搜索,而不是XML。 - Cerebrus
当前的浏览器都支持XPath,它主要是为DOM实现的。 - Azder

0

你可以快速阅读文档树的主体并对其进行简单的字符串测试,而无需深入了解 - 这取决于你正在处理的 HTML 的一些控制程度 - 你对页面有多少控制权?如果你在自己控制的网站上工作,你可能可以将搜索重点放在页面上可能与其他页面不同的部分,如果你在处理其他人的页面,那么你的工作就更加困难,因为你不一定知道需要针对哪些内容进行测试。

同样,如果你要多次搜索同一页,并且数据集很大,那么在内存中创建某种索引可能是值得的,而如果你只要搜索几个单词或使用较小的文档,则构建它可能不值得时间和复杂性。

也许最好的方法是获取一些你认为代表性的示例文档,并基于这里提供的方法进行大量的原型设计。


0
form.addEventListener("submit", (e) => {
e.preventDefault();
var keyword = document.getElementById("search_input");
let words = keyword.value;
var word = words,
    queue = [document.body],
    curr;
while (curr = queue.pop()) {
    if (!curr.textContent.toUpperCase().match(word.toUpperCase())) continue;
    for (var i = 0; i < curr.childNodes.length; ++i) {
        switch (curr.childNodes[i].nodeType) {
            case Node.TEXT_NODE: // 3
                if (curr.childNodes[i].textContent.toUpperCase().match(word.toUpperCase())) {
                    console.log("Found!");
                    console.log(curr);
                    curr.scrollIntoView();
                }
                break;
            case Node.ELEMENT_NODE: // 1
                queue.push(curr.childNodes[i]);
                break;
        }
    }
}

});


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接