【问题标题】:How to wait for HTML document to load/render before printing it (plain JavaScript)如何在打印之前等待 HTML 文档加载/渲染(纯 JavaScript)
【发布时间】:2018-01-29 09:50:28
【问题描述】:

我正在使用此代码在新的 html 页面上打开和打印图像:

printView(dataUri:string){

  var win = window.open();
  win.document.write( '<img src="' + dataUri + '">');

  win.print();
  win.close();

}

当这样使用并且图像大于几 kB 时,打印预览会打开一个空白页面,因为调用打印时不会呈现文档。

我通过引入setTimeout(在打印前延迟约 200 毫秒)解决了这个问题,如下所示:

setTimeout( () => {
     win.print();
     win.close();
}, 200);

这可行,但是我知道我应该使用一些 DOM/窗口事件来等待内容加载。但是哪一个?

到目前为止我尝试了什么:

win.document.onload = ()=>{
    console.log('event fired'); // never fired
    win.print();
    win.close();
}

win.addEventListener('load', ()=>{
    console.log('event fired'); // never fired
    win.print();
    win.close();
}

我想保留这个 Vanilla JS,所以请不要让我参考 jQuery window.ready。

【问题讨论】:

  • “等待 HTML 文档加载”是什么意思?一旦你执行 window.open(),就会创建一个新文档并自动加载,因为它最初是空的
  • 我相信你的 win.document.onload 事件没有被触发,因为你在 window.open() 之后定义它们,当你绑定事件处理程序时,事件已经被调用
  • 您的主要问题是您希望页面仅在特定条件后加载!在您在此问题中指定的示例中,您只有 1 个条件,即(加载图像后加载)
  • 考虑到这些事实,我们可以得出结论,没有 DOM 方法或事件处理程序可以帮助您!
  • 我可以建议您一个解决方案,但由于您的加载实际上不是文档的加载,因此您必须在每次更改或添加加载后应该准备好的内容时更新它!

标签: javascript typescript onload dom-events


【解决方案1】:

为您的图片添加 onload 属性

 win.document.write( '<img src="' + dataUri + '" onload="print()">');

printView()

中删除 win.print()win.close()

并将它们添加到另一个函数print()

print() 将在图像完成加载时触发。

这次希望成功

【讨论】:

  • 按我的意愿工作!谢谢。
  • 感觉很开心,因为我可以帮助你 :D :D
  • 我认为您编辑的答案不如原始答案。在图像加载缓慢的情况下,调用堆栈溢出的可能性 - 两个函数相互调用无数次,直到满足条件。如果图像从外部源加载并且连接中断怎么办?
  • 哦!谢谢。实际上,我并没有从那个角度思考。您知道程序中总是存在错误。我已将其编辑为原件。
【解决方案2】:

我知道它已经回答了,但我需要打印一个包含大量 html 内容的新窗口并使用如下内容:

win.document.addEventListener('DOMContentLoaded', this.print());

【讨论】:

    【解决方案3】:

    在页面底部包含脚本标记应该可以工作。 因为浏览器从上到下读取html页面, 当脚本位于页面底部时,它将在页面加载后触发事件。

    【讨论】:

    • 感谢您的快速回答。它应该工作,但它没有。当我在末尾添加win.document.write( '&lt;script&gt; window.print(); window.close();&lt;/script&gt;'); 时,脚本的执行方式与我的示例中的相同:尚未加载图像。即使我在脚本中添加defer 属性,结果也是一样的……
    • 您可以尝试另一种方法,但我不确定。我正在发布另一个答案
    【解决方案4】:

    What is the non-jQuery equivalent of '$(document).ready()'?复制 domready.js

    (function(exports, d) {
      function domReady(fn, context) {
    
        function onReady(event) {
          d.removeEventListener("DOMContentLoaded", onReady);
          fn.call(context || exports, event);
        }
    
        function onReadyIe(event) {
          if (d.readyState === "complete") {
            d.detachEvent("onreadystatechange", onReadyIe);
            fn.call(context || exports, event);
          }
        }
    
        d.addEventListener && d.addEventListener("DOMContentLoaded", onReady) ||
        d.attachEvent      && d.attachEvent("onreadystatechange", onReadyIe);
      }
    
      exports.domReady = domReady;
    })(window, document);
    

    如何使用它

    <script src="domready.js"></script>
    <script>
      domReady(function(event) {
        alert("dom is ready!");
      });
    </script>
    

    【讨论】:

    • 谢谢。如果我是正确的,它本质上是为“DOMContentLoaded”事件添加 EventListener,对吧?在我对原始问题的第二次尝试中,我还尝试 addEventListener 获取 DOMContentLoaded,但它也从未触发过......
    【解决方案5】:

    在这里,主要基于Imtiaz的想法:

    var win = window.open();
    var img = win.document.createElement("img");
    img.onload = function(){
        win.print();
        win.close();
    }
    img.src = dataUri;
    win.document.body.appendChild(img);
    

    我只是觉得用脚本来做比较干净,而不是用一个脚本把另一个脚本写成html……

    【讨论】:

      猜你喜欢
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 2020-02-08
      • 2017-10-29
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多