文本内容高亮
javascript
/**
* 高亮显示容器中的关键字。
*
* @param container - 要搜索和高亮显示关键字的 DOM 容器。
* @param keyword - 要高亮显示的关键字。
*/
highlight(container: any, keyword: string) {
// 如果浏览器不支持 CSS Custom Highlight API,直接返回并输出错误信息
if (!CSS.highlights) {
console.error('CSS Custom Highlight API is not supported in this browser.');
return;
}
// 清除先前的高亮显示
// @ts-expect-error: 临时解决缺少 HighlightRegistry 类型的问题。
CSS.highlights.clear(); // 如果需要清除特定名称的高亮显示,请使用 CSS.highlights.delete('highlightName')
// 如果关键字为空,则返回
if (keyword === '') return;
// 使用 TreeWalker 查找所有文本节点
const treeWalker = document.createTreeWalker(
container, NodeFilter.SHOW_TEXT,
{
acceptNode: (node) => {
return node.nodeValue?.toLowerCase().includes(keyword.toLowerCase())
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_REJECT;
},
},
);
// 创建 Highlight 对象并注册
const highlight = new Highlight();
// 遍历所有符合条件的文本节点
while (treeWalker.nextNode()) {
const node = treeWalker.currentNode;
// 跳过特定条件下的节点(例如父节点是 APP-CHAT-MESSAGE 的情况)
if (node.parentNode?.parentNode?.nextSibling?.nodeName === 'APP-CHAT-MESSAGE') {
continue;
}
let content = node.nodeValue;
const lowerCaseKeyword = keyword.toLowerCase();
let startIndex = content?.toLowerCase().indexOf(lowerCaseKeyword);
// 如果找不到关键字,则继续下一个节点
if (startIndex === -1 || startIndex === undefined) {
continue;
}
// 循环查找并高亮显示所有匹配的关键字
while (startIndex !== undefined && startIndex !== -1) {
const range = new Range();
range.setStart(node, startIndex);
range.setEnd(node, startIndex + keyword.length);
// @ts-expect-error: 临时解决缺少 HighlightRegistry 类型的问题。
highlight.add(range); // 高亮对象添加范围
content = node.nodeValue;
startIndex = content?.toLowerCase().indexOf(lowerCaseKeyword, startIndex + keyword.length);
}
}
// 在 HighlightRegistry 中注册高亮实例
// @ts-expect-error: 临时解决缺少 HighlightRegistry 类型的问题。
CSS.highlights.set('highlightName', highlight); // 'highlightName' 是自定义的标识符
}