【问题标题】:PDF.JS - Detect when page has been renderedPDF.JS - 检测页面何时呈现
【发布时间】:2025-11-28 11:40:01
【问题描述】:

一旦 PDF.JS 完成渲染每个页面,我想然后对该页面的内容进行查找/替换。

我通过将以下内容放入 iFrame 的文档中来调用 PDF.JS:

<script>
fileId=0;
function getURLParameter(name) {
  return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null
}
var fileId = getURLParameter("fileId");
var DEFAULT_URL = '/viewer/fetchpdf.php?fileId='+fileId;
</script>

然后从父框架设置 URL:

url = '/_third_party/pdfjs/web/viewer.html?fileId='+$(this).attr('href');
$("#iframeViewPdf").attr('src', url);

我注意到在使用 PDF.JS 呈现 PDF 时,它会使用加载占位符初始化每个页面:

<div id="pageContainer3" class="page" style="width: 991px; height: 1319px;">
    <div class="loadingIcon"></div>
</div>
<div id="pageContainer4...

然后它将 PDF 呈现为 html,例如

<div id="pageContainer3" class="page" style="width: 991px; height: 1319px;">
    <div class="canvasWrapper" style="width: 991px; height: 1319px;">
        <canvas id="page46" width="991" height="1319" style="width: 991px; height: 1319px;">
        </canvas>
    </div>
    <div class="textLayer" style="width: 991px; height: 1319px;">
        ...
    </div>
</div>
<div id="pageContainer4...

【问题讨论】:

    标签: javascript jquery html dom pdf.js


    【解决方案1】:

    经过澄清,这是一个非常不同的故事。您不是直接使用 PDF.JS,而是使用它们的网络包装器。我认为你可以使用的一件事(我从来没有做过,现在只是阅读代码)是他们在document 上发出pageRendered 事件,所以如果你可以添加一个监听器,你应该没问题:

    var frameDoc = document.getElementById('iframeViewPdf').contentWindow.document;
    
    frameDoc.addEventListener('pagerendered', function (evt) {
      console.log(evt); // see what goodies hide here! like page number etc
    }
    

    (未测试,可能需要调整。)

    【讨论】:

    • 您好,谢谢您的建议。解决方案缺少最后一个括号。不幸的是,似乎没有发现任何事件,现在玩它看看我是否能找出原因。
    • 我发现以下代码有效,您可以编辑您的答案以反映这一点吗? $( "#iframeViewPdf" ).load(function() { // 等待 iframe 加载 var frameDoc = $("#iframeViewPdf").contents()[0]; frameDoc.addEventListener("pagerendered", function (evt ) { console.log(evt.detail); }); });
    【解决方案2】:

    这就是我们检测页面渲染的方式。在设置监听器之前等待 iframe 内容加载很重要。

    $( "#iframeViewPdf" ).load(function() { // wait for iframe to load
        var frameDoc = $("#iframeViewPdf").contents()[0];     
        frameDoc.addEventListener("pagerendered", function (evt) { 
            console.log(evt.detail);
        });
    });
    

    【讨论】:

      【解决方案3】:
      //Step 1: store a refer to the renderer
      var pageRendering = page.render(renderContext);
      //Step : hook into the pdf render complete event
      var completeCallback = pageRendering.internalRenderTask.callback;
      pageRendering.internalRenderTask.callback = function (error) {
        //Step 2: what you want to do before calling the complete method                  
        completeCallback.call(this, error);
        //Step 3: do some more stuff
      };
      

      【讨论】:

      • 如果我没看错文档,page.render 会返回一个承诺,为什么不page.render(...).next(function...)?从长远来看,我看不出弄乱内部的东西是健康的……
      • @Amadan 我猜您正在阅读文档,您可以并且可能必须这样做。这只是实现相同目标的另一种方式。
      • @Amadan - 请您提供更多细节,我不太确定如何实施您的建议?
      • 我可以对你说同样的话 :) 你的问题并不有趣,PDF.JS 到底有什么作为渲染结果,但是你完全忽略了重要的东西:你在 JavaScript 中调用它的方式。
      • @Amadan - 很公平。我已经解释了我是如何调用它的,我在使用默认的 pdfjs 实现之前设置了 defaulturl。
      最近更新 更多