如何使用pdf.js同时高亮PDF中的多个非连续单词
解决PDF.js高亮多个非连续单词的问题
你之前用循环修改URL #search 参数的方式行不通,因为每次设置hash都会让PDF.js重新执行搜索,覆盖之前的高亮结果,最后只剩最后一个单词被高亮。以下是两种可行的方案:
方案一:直接操作文本层DOM实现高亮
如果已经手动加载了PDF文档,可以通过解析页面文本内容,手动创建高亮元素添加到文本层:
// 假设doc是已加载的PDFDocumentProxy实例 const targetWords = ["printing", "industry"]; // 遍历所有页面 for (let pageNum = 1; pageNum <= doc.numPages; pageNum++) { doc.getPage(pageNum).then(page => { return page.getTextContent().then(textContent => { const textItems = textContent.items; const textLayer = document.querySelector(`#pageContainer${pageNum} .textLayer`); if (!textLayer) return; targetWords.forEach(word => { const regex = new RegExp(word, 'gi'); textItems.forEach(item => { let match; // 查找当前文本项中所有匹配的关键词 while ((match = regex.exec(item.str)) !== null) { // 创建高亮span const highlightSpan = document.createElement('span'); highlightSpan.className = 'custom-highlight'; highlightSpan.style.cssText = ` position: absolute; left: ${item.transform[4]}px; top: ${item.transform[5] - item.height}px; width: ${item.width}px; height: ${item.height}px; background-color: yellow; opacity: 0.6; `; textLayer.appendChild(highlightSpan); } }); }); }); }); }
方案二:使用PDF.js Viewer的内置搜索控制器
如果你用的是PDF.js官方提供的Viewer组件,可以调用findController的API批量高亮关键词:
// 假设viewer是PDFViewer实例 const targetWords = ["printing", "industry"]; targetWords.forEach(word => { viewer.findController.executeCommand('find', { query: word, highlightAll: true, // 高亮所有匹配项 caseSensitive: false, findPrevious: false }); });
关键说明
- URL的
#search参数是单次搜索触发,多次修改会覆盖之前的搜索状态,这就是你之前循环只生效最后一个单词的原因。 - 两种方案都需要确保PDF文档已经加载完成,文本层DOM已生成。
内容的提问来源于stack exchange,提问作者Sumit T
相关产品推荐
相关产品推荐

