PDF.js渲染部分PDF页面时出现黑色矩形问题求助
问题分析与修复方案
你遇到的黑色矩形遮挡问题,核心是文本层(textLayer)未正确初始化和挂载,加上代码里的几个细节错误导致的。官方示例完整实现了文本层的渲染流程,而你的代码只创建了textLayer元素却没完成后续步骤,部分PDF的特殊文本排版触发了异常。
具体问题点
- 创建的
textLayer元素未添加到DOM中,也未调用PDF.js的文本层渲染API,导致文本层的占位元素出现异常黑块 canvas.width设置为字符串'600',应该使用数字类型,会干扰渲染比例计算- 缺少文本层必需的CSS样式,官方
textLayer类需要特定样式才能正常显示
修复后的代码
修改initPdf函数
function initPdf(url){ const { pdfjsLib } = globalThis; pdfjsLib.GlobalWorkerOptions.workerSrc = 'js/pdfjs/build/pdf.worker.mjs'; const loadingTask = pdfjsLib.getDocument(url); loadingTask.promise.then(function(pdf) { const thePdf = pdf; const viewer = document.getElementById('pdf-viewer'); for(let page = 1; page <= pdf.numPages; page++) { // 用容器包裹canvas和textLayer,保证层级正确 const pageContainer = document.createElement("div"); pageContainer.className = 'pdf-page-container'; const canvas = document.createElement("canvas"); canvas.id = 'pdfCanvas'+page; canvas.className = 'pdf-page-canvas'; canvas.width = 600; // 改为数字类型 const textLayer = document.createElement("div"); textLayer.id = 'textLayer'+page; textLayer.className = 'textLayer'; pageContainer.appendChild(canvas); pageContainer.appendChild(textLayer); viewer.appendChild(pageContainer); renderPage(page, canvas, textLayer, thePdf); } }); }
修改renderPage函数
function renderPage(pageNumber, canvas, textLayer, pdf) { pdf.getPage(pageNumber).then(function(page) { const viewport = page.getViewport({ scale: 1 }); const scale = canvas.width / viewport.width; const scaledViewport = page.getViewport({ scale: scale }); canvas.height = scaledViewport.height; const renderContext = { canvasContext: canvas.getContext('2d'), viewport: scaledViewport }; // 先渲染画布,再渲染文本层 const renderTask = page.render(renderContext); renderTask.promise.then(function() { // 获取文本内容并渲染到文本层 return page.getTextContent(); }).then(function(textContent) { pdfjsLib.renderTextLayer({ textContent: textContent, container: textLayer, viewport: scaledViewport, textDivs: [] }); }); }); }
必需的CSS样式
需要添加文本层的基础样式(可从PDF.js官方示例中提取),否则仍可能出现显示异常:
.textLayer { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; opacity: 0.2; /* 可根据需求调整,官方默认是0.2,设为0则隐藏文本层 */ line-height: 1; } .textLayer > div { color: transparent; position: absolute; white-space: pre; cursor: text; transform-origin: 0% 0%; } .pdf-page-container { position: relative; margin-bottom: 10px; /* 页面间距,可调整 */ } .pdf-page-canvas { display: block; }
额外说明
- 变量尽量用
const/let声明,避免全局变量污染 - 文本层的
opacity可以根据需求调整,如果不需要选中文本功能,也可以直接不渲染文本层(去掉相关代码),但部分PDF的渲染依赖文本层的排版信息,建议保留
内容的提问来源于stack exchange,提问作者Roldan
相关产品推荐
相关产品推荐

