96SEO 2026-06-06 14:45 19
嘿,老铁们,今天咱聊聊电子书里的笔记高亮。说实话,以前我也只会在同一段里点个星星,然后保存到云端,等着翻页找。可你想不想一次性把跨行、跨段的内容dou搞定?那就得给浏览器的DOM玩点小手脚。
先说个背景在阅读器里高亮其实就是给文本包一个span标签。你选中一块文字,系统就会把对应的Range拆出来再插入个span。这玩意儿hen灵活,但有个大坑:当你选中的文本跨越了几个 大多数实现只处理单段Range,那Ru果你选中的是“第一段……第二段……”,系统就只会高亮第一段,第二段就被忽略了。这个问题在学术论文或长篇小说里尤为突出。 核心思路是:先把整篇内容拆成一个个文本节点,然后按位置映射回全局索引。这样无论哪一行,你douNeng算出它在全文里的起止位置,从而统一管理高亮。 我们用 那啥是啥?简言之,每个文本节点现在dou有自己的start和end属性,代表它在全文里的绝对位置。 这一步其实hen熟悉: #但要注意!# Ru果你的页面是http而不是https, #这里才是关键#:我们拿到起始节点和结束节点,然后在前面得到的nodeMap里找对应的位置: #说明#:因为RangeKe以跨多个节点,所以这里必须逐节点累加长度才Neng得到真正的位置。Ru果直接用range.startOffset+endOffset,就会错乱。 =当用户抬起鼠标后我们往往想弹出一个小工具条,让他Neng马上写笔记或复制文字。要Zuo到这一点,需要把弹窗定位到选中的第一个矩形上。
`getClientRects`: `getBoundingClientRect`: #二者区别#:前者返回所有矩形,后者返回覆盖全部的Zui小矩形。咱一般用前者,因为我们想让弹窗跟随第一行。 #注意#:滚动偏移量要加上,否则滚到页面底部时弹窗会跑到视口外面去。 #下面给你一个完整的实现框架,你Ke以直接套进去,用自己的样式替换一下即可。# 别忘了 CSS 的类名和动画效果哦~
`highlightText`: `removeHighlights`: `saveNoteToDB`: `loadNotesFromDB`: #温馨提示#:Ru果你的阅读器支持多设备同步,把笔记存进服务器而不是localStoragegeng靠谱。不过那就多写点接口啦,我先不管了。 #别担心,一旦你掌握了上述方案,它几乎Neng兼容任何基于DOM渲染的阅读器:EPUB.js、PDF.js、甚至自定义渲染器。因为所有操作dou是通过标准DOM API完成的,不依赖特定库内部实现。
① Range API 是浏览器原生提供,可保证不同渲染方式下的一致性;
② 文本节点拆分策略可应对各种排版结构;
③ 高度自定义化样式让你随心所欲地配色、动画;
④ 跨域安全策略需留意 clipboard 与 https 的关系。
#标题标签优化#——使用关键字如“电子书”“高亮笔记”“跨段识别”放在H1/H2里;
#Meta描述#——一句简短但信息量大的描述,让搜索结果展示你的特色;
#图片 alt 属性#——若有图表或示例截图,加上“电子书高亮演示”等 alt 文本;
#结构化数据#——使用 schema.org/Book 来标注书籍信息,提高可读性;
#移动友好度#——响应式布局和触控友好的 UI Neng提升搜索排名。
说真的,技术再牛也离不开用户体验。Ru果你觉得代码写起来麻烦,Ke以先用现成库Zuo实验,比如 KoodoReader 或 Readium,它们Yi经有不错的高亮逻辑。但Ru果你想要完全掌控,那上面的方案足够用了。慢慢调试、调试、再调试,你一定Neng搞定跨段识别,让读者一次性kan到完整摘录,省掉翻页查找的痛苦!哈哈~ 别忘了给自己点赞,也欢迎留言讨论~ 🚀 
document.createTreeWalker来遍历,只接受非空的文本节点:
const getAllNodes = => {
if return ;
const walker = document.createTreeWalker(
contentRef,
NodeFilter.SHOW_TEXT,
{
acceptNode: node => node.textContent?.trim ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT
}
);
const nodes = ;
let node;
while )) nodes.push;
// 累加长度得到全局索引
let total = 0;
return nodes.map(n => {
const txt = n.textContent ?? "";
const start = total;
total += txt.length;
return { node: n, text: txt, start, end: total };
});
};
const selection = window.getSelection;
if return null;
const range = selection.getRangeAt;
const selectedText = selection.toString.trim;
console.log;
可被禁用,要么改成https,要么放弃剪贴板功Neng。
const mapNodes = getAllNodes;
let globalStart = -1;
let globalEnd = -1;
for {
if {
globalStart = start + range.startOffset;
}
if {
globalEnd = start + range.endOffset;
}
}
if return null;
// 确保顺序正确
if = ;
console.log;
return { selectedText, globalStart, globalEnd };
const rects = range.getClientRects;
const firstRect = rects; // 第一个矩形
const pos = {
top: firstRect.top + window.scrollY,
left: firstRect.left + window.scrollX
};
console.log;
// 然后把pos传给你的弹窗组件去定位
// 移除Yi有高亮
function removeHighlights{
const spans=ref.querySelectorAll;
spans.forEach)});
}
// 高亮函数
function highlightText{
removeHighlights;
const map=getAllNodes;
const hls=;
for{
const ns=Math.max;
const ne=Math.min;
if continue; // 无效区间
const r=document.createRange;
r.setStart;
r.setEnd;
hls.push;
}
// 按从后往前排序防止位移
hls.sort=>b.range.startOffset-a.range.startOffset);
hls.forEach=>{
const span=document.createElement;
span.className=className;
span.dataset.noteId=id;
span.appendChild);
range.insertNode;
});
}
// 保存笔记
function saveNoteToDB{
localStorage.setItem);
}
function loadNotesFromDB{
Object.keys
.filter)
.map))
.forEach);
}
window.addEventListener;
// 鼠标抬起事件处理
contentRef.addEventListener=>{
const sel=window.getSelection;
ifreturn;
// 获取位置信息并保存
const note=getSelectionPosition; // 用上面那份代码实现
note.id=`n${Date.now}`;
// 弹出编辑框
showPopupAt=>{
note.selectedText=text;
saveNoteToDB;
highlightText;
hidePopup;
});
});
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback