You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
});

问题排查与解决方法

核心问题分析

  1. 单注释层复用导致多页重叠:所有页面的注释都渲染到同一个#annotation-layer,会导致注释位置混乱、多页注释重叠。
  2. CSS定位错误:设置注释层宽高时错误使用pdf_canvas(这是offset()返回的坐标对象,不是尺寸数值),导致样式失效。
  3. AnnotationLayer缺少必要配置:渲染注释层时未传入linkService或externalLinkTarget,PDF.js无法处理链接跳转逻辑,触发externalLinkTarget读取错误。

具体修复步骤

  1. 修改页面结构,每页对应独立容器
    为每个PDF页面创建包含canvas和注释层的容器,确保注释层与对应页面canvas绑定,无需提前写死注释层。

  2. 修复渲染代码

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);
});
  1. 添加注释层基础样式
    确保注释链接可点击,添加CSS:
.annotationLayer a {
    display: block;
    position: absolute;
    cursor: pointer;
}

修复说明

  • 为每个页面创建独立容器,避免注释层重叠,定位更准确。
  • 自定义linkService并传入AnnotationLayer,解决externalLinkTarget未定义的问题,同时实现外部链接跳转逻辑。
  • 修复CSS尺寸设置错误,使用viewport的宽高定义容器和注释层尺寸。

内容的提问来源于stack exchange,提问作者HaroonM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 06:11:00