如何自定义文档高亮hooks为?
摘要:在现在项目开发中,文本高亮是一个常见且实用的功能,尤其在一些涉及做题网站、阅读类应用、笔记工具或内容管理系统中。废话不多说直接看实现: 功能亮点 支持鼠标选中文本后自动高亮 可选的双击高亮功能 处理跨段落、跨元素的文本高亮 点击高亮区域可直
在现在项目开发中,文本高亮是一个常见且实用的功能,尤其在一些涉及做题网站、阅读类应用、笔记工具或内容管理系统中。废话不多说直接看实现:
功能亮点
支持鼠标选中文本后自动高亮
可选的双击高亮功能
处理跨段落、跨元素的文本高亮
点击高亮区域可直接取消高亮
提供清除单个或所有高亮的方法
支持自定义高亮颜色
高亮事件回调机制
自动处理文本节点合并,保持 DOM 结构整洁
核心实现解析
1. 类型定义与初始化
export interface HighlightRange {
id: string; // 唯一标识
startContainer: Node; // 起始节点
startOffset: number; // 起始偏移量
endContainer: Node; // 结束节点
endOffset: number; // 结束偏移量
text: string; // 高亮文本内容
}
初始化部分处理配置选项和响应式变量:
export function useTextHighlight(
containerRef: Ref<HTMLElement | null>,
options: {
highlightColor?: string;
enableDoubleClick?: boolean;
onHighlight?: (range: HighlightRange) => void;
} = {}
) {
const {
highlightColor = "#ffeb3b", // 默认黄色高亮
enableDoubleClick = false,
onHighlight,
} = options;
const highlights = ref<Map<string, HighlightRange>>(new Map());
const isHighlighting = ref(false);
// ...
}
2. 跨节点高亮的核心解决方案
文本高亮的主要难点是跨节点选择(例如选中的文本跨越多个 <p> 标签或 <span> 标签)。这边用了 highlightCrossNodes 方法处理这个问题。
