PDF.js 2.10.377注释链接无法点击且报externalLinkTarget错误求助
PDF.js 2.10.377注释链接无法点击,报错
TypeError: Cannot read properties of undefined (reading 'externalLinkTarget') 报错信息
pdf.min.js:22 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'externalLinkTarget') at LinkAnnotationElement.render (pdf.min.js:22:1) at Function.render (pdf.min.js:22:1) at eval (eval at <anonymous> (jquery.min.js:2:1), <anonymous>:32:48)
相关代码
原HTML结构
<div id="canvasPDFViewer" class="canvasPDFViewer"></div> <div class="annotationLayer" id=”annotation-layer”></div>
引入的JS
<script defer> window.pdfjsLib.GlobalWorkerOptions.workerSrc = '/_js/pdf.worker.min.js'; </script>
原PDF渲染代码
let loadingTask = pdfjsLib.getDocument(url); loadingTask.promise.then(function(pdf) { let totalPageNumber = pdf.numPages; for(let pageNumber = 1; pageNumber <= totalPageNumber; pageNumber++) { pdf.getPage(pageNumber).then(function(page) { let scale = 1; let viewport = page.getViewport({ scale: scale }); let canvas = document.createElement("canvas"); canvas.height = viewport.height; canvas.width = viewport.width; let canvasContext = canvas.getContext("2d"); let renderContext = { canvasContext: canvasContext, viewport: viewport }; page.render(renderContext).promise.then(function() { return page.getAnnotations(); }).then(function(annotationData) { if(annotationData.length == 0) return; var pdf_canvas = $(canvas).offset(); $("#annotation-layer").css({ left: pdf_canvas.left + "px", top: pdf_canvas.top + "px", height: pdf_canvas + "px", width: pdf_canvas + "px" }); pdfjsLib.AnnotationLayer.render({ viewport: viewport.clone({ dontFlip: true }), div: $("#annotation-layer").get(0), annotations: annotationData, page: page }); }); document.getElementById("canvasPDFViewer").appendChild(canvas); }); } }, function (reason) { // PDF loading error // console.error(reason); });
问题排查与解决方法
核心问题分析
- 单注释层复用导致多页重叠:所有页面的注释都渲染到同一个
#annotation-layer,会导致注释位置混乱、多页注释重叠。 - CSS定位错误:设置注释层宽高时错误使用
pdf_canvas(这是offset()返回的坐标对象,不是尺寸数值),导致样式失效。 - AnnotationLayer缺少必要配置:渲染注释层时未传入
linkService或externalLinkTarget,PDF.js无法处理链接跳转逻辑,触发externalLinkTarget读取错误。
具体修复步骤
修改页面结构,每页对应独立容器
为每个PDF页面创建包含canvas和注释层的容器,确保注释层与对应页面canvas绑定,无需提前写死注释层。修复渲染代码
let loadingTask = pdfjsLib.getDocument(url); loadingTask.promise.then(function(pdf) { let totalPageNumber = pdf.numPages; const viewerContainer = document.getElementById("canvasPDFViewer"); // 实现基础链接服务,处理外部链接跳转 const linkService = { externalLinkTarget: pdfjsLib.LinkTarget.BLANK, openLink: function(url) { window.open(url, this.externalLinkTarget); } }; for(let pageNumber = 1; pageNumber <= totalPageNumber; pageNumber++) { pdf.getPage(pageNumber).then(function(page) { let scale = 1; let viewport = page.getViewport({ scale: scale }); // 创建页面容器,包含canvas和注释层 const pageContainer = document.createElement("div"); pageContainer.style.position = "relative"; pageContainer.style.width = `${viewport.width}px`; pageContainer.style.height = `${viewport.height}px`; // 创建canvas let canvas = document.createElement("canvas"); canvas.height = viewport.height; canvas.width = viewport.width; pageContainer.appendChild(canvas); // 创建当前页的注释层div const annotationLayer = document.createElement("div"); annotationLayer.className = "annotationLayer"; annotationLayer.style.position = "absolute"; annotationLayer.style.top = "0"; annotationLayer.style.left = "0"; annotationLayer.style.width = `${viewport.width}px`; annotationLayer.style.height = `${viewport.height}px`; pageContainer.appendChild(annotationLayer); viewerContainer.appendChild(pageContainer); let canvasContext = canvas.getContext("2d"); let renderContext = { canvasContext: canvasContext, viewport: viewport }; page.render(renderContext).promise.then(function() { return page.getAnnotations(); }).then(function(annotationData) { if(annotationData.length === 0) return; pdfjsLib.AnnotationLayer.render({ viewport: viewport.clone({ dontFlip: true }), div: annotationLayer, annotations: annotationData, page: page, linkService: linkService // 传入链接服务配置 }); }); }); } }, function (reason) { console.error(reason); });
- 添加注释层基础样式
确保注释链接可点击,添加CSS:
.annotationLayer a { display: block; position: absolute; cursor: pointer; }
修复说明
- 为每个页面创建独立容器,避免注释层重叠,定位更准确。
- 自定义
linkService并传入AnnotationLayer,解决externalLinkTarget未定义的问题,同时实现外部链接跳转逻辑。 - 修复CSS尺寸设置错误,使用viewport的宽高定义容器和注释层尺寸。
内容的提问来源于stack exchange,提问作者HaroonM
相关产品推荐
相关产品推荐

