为什么在主窗口中打印后会触发打印事件侦听器后的iframe?

时间:2019-09-02 11:37:47

标签: javascript typescript dom-events

export const printPdf = (data: any) => {
  const newBlob = new Blob([data], { type: 'application/pdf' })
  const fileLink = window.URL.createObjectURL(newBlob)
  const iframe = document.createElement('iframe')
  iframe.src = fileLink
  iframe.id = 'print_pdf'
  iframe.name = 'print_pdf'
  // iframe.style.display = 'none'
  iframe.onload = () => {
    iframe.contentWindow!.addEventListener('afterprint', () => {
      document.body.removeChild(iframe)
    })
  }
  document.body.appendChild(iframe)
  window.frames['print_pdf'].focus()
  window.frames['print_pdf'].print()
}

因此,在iframe完成打印后,什么也没发生。但是,在对话框关闭后打印主页时。侦听器iframe.contentWindow!.addEventListener('afterprint', ()开始执行。为什么iframe不监听自身的打印事件?

1 个答案:

答案 0 :(得分:1)

这是因为您没有在调用print()方法之前等待框架内容已加载,而是在附加事件侦听器之前等待。
因此,在附加事件侦听器之前会出现打印对话框,这会阻止js,然后触发打印事件,然后附加事件。

如果您在页面加载后调用了print(),您将获得正常的行为,并且监听器将触发:https://jsfiddle.net/xonq5r37/

iframe.onload = () => {
  iframe.contentWindow!.addEventListener('afterprint', (evt) => {
    document.body.removeChild(iframe)
  });
  window.frames['print_pdf'].focus()
  window.frames['print_pdf'].print()
};

关于当您在主窗口上调用print()时事件在框架窗口上触发的原因,这很正常,因为iframe是要打印的文档的一部分,所以它也将接收此事件。 / p>

来自the specs

  

用户代理必须在正在打印的afterprint的{​​{3}}以及其中的任何relevant global object处触发名为Document的事件。