我会用DOMParser
确保我们正在进行一些“智能”搜索。假设您正在寻找有关“viewport”一词的文本;您不需要任何具有以下内容的 HTML 文件<meta>
标记“viewport”以作为有效结果返回,可以吗?
第一步是将字符串解析为 Document 实例:
const parseHTMLString = (() => {
const parser = new DOMParser();
return str => parser.parseFromString(str, "text/html");
})();
在这里输入一个有效的 HTML 字符串,您将得到一个返回的文档,其行为类似于window.document
!这意味着我们可以做各种很酷的事情,比如使用querySelector
和类似的属性innerText
.
下一步是定义我们要搜索的内容。下面是一个连接文档标题和正文的示例:
const getSearchStringForDoc = doc => {
return [ doc.title, doc.body.innerText ]
.map(str => str.toLowerCase().trim())
.join(" ");
};
将解析后的文档传递给此函数,您将得到一个纯字符串作为回报,其中仅包含内容,没有属性、标签名称和元数据。
现在,问题是定义正确的搜索方法。可能是基于正则表达式的匹配,或者只是(速度较慢)split
& includes
:
const stringMatchesQuery = (str, query) => {
return query
.toLowerCase()
.split(/\W+/)
.some(q => str.includes(q))
};
将这些方法链接在一起,您将得到如下转换:
String -> Document -> String -> Boolean
如果您想在搜索内容中包含更多信息,只需更新getSearchStringForDoc
使用标准化 API 的功能。
一个正在运行的示例(有点混乱,可以进行一些重构,但希望能明白要点):
const htmlString = (
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The title</title>
</head>
<body>
Some text about an interesting thing.
</body>
</html>`);
const parseHTMLString = (() => {
const parser = new DOMParser();
return str => parser.parseFromString(str, "text/html");
})();
const getSearchStringForDoc = doc => {
return [
doc.title,
doc.body.innerText
].map(str => str.trim())
.join(" ");
};
const stringMatchesQuery = (str, query) => {
str = str.toLowerCase();
query = query.toLowerCase();
return query
.split(/\W+/)
.some(q => str.includes(q))
};
const htmlStringMatchesQuery = (str, query) => {
const htmlDoc = parseHTMLString(str);
const htmlSearchString = getSearchStringForDoc(htmlDoc);
return stringMatchesQuery(htmlSearchString, query);
};
console.log("Match 'viewport':", htmlStringMatchesQuery(htmlString, "viewport"));
console.log("Match 'Interesting':", htmlStringMatchesQuery(htmlString, "Interesting"));