如何检测 window.print() 完成

How to detect window.print() finish

本文关键字:window print 完成 检测 何检测      更新时间:2023-09-26

在我的应用程序中,我尝试为用户打印出一个凭证页面,如下所示:

  var htm ="<div>Voucher Details</div>";
  $('#divprint').html(htm);
  window.setTimeout('window.print()',2000);
'

divprint ' 是我页面中的一个div,用于存储有关代金券的信息。

它有效,并弹出打印页面。但是我想在用户单击浏览器弹出的打印对话框中的"print"或"close"后推进应用程序。

例如,我想在弹出窗口关闭后将用户重定向到另一个页面:

window.application.directtoantherpage();//a function which direct user to other page

如何确定弹出窗口何时关闭或打印完成?

您可以收听 afterprint 事件。

https://developer.mozilla.org/en-US/docs/Web/API/window.onafterprint

window.onafterprint = function(){
   console.log("Printing completed...");
}

可以使用 window.matchMedia 以另一种方式获取此功能。

(function() {
    var beforePrint = function() {
        console.log('Functionality to run before printing.');
    };
    var afterPrint = function() {
        console.log('Functionality to run after printing');
    };
    if (window.matchMedia) {
        var mediaQueryList = window.matchMedia('print');
        mediaQueryList.addListener(function(mql) {
            if (mql.matches) {
                beforePrint();
            } else {
                afterPrint();
            }
        });
    }
    window.onbeforeprint = beforePrint;
    window.onafterprint = afterPrint;
}());

来源: http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/

在镀铬 (V.35.0.1916.153 m( 上试试这个:

function loadPrint() {
    window.print();
    setTimeout(function () { window.close(); }, 100);
}

对我来说效果很好。用户完成打印对话框后,它将关闭窗口。

兼容chrome,Firefox,opera,Internet Explorer
注意:需要 jQuery。

<script>
    window.onafterprint = function(e){
        $(window).off('mousemove', window.onafterprint);
        console.log('Print Dialog Closed..');
    };
    window.print();
    setTimeout(function(){
        $(window).one('mousemove', window.onafterprint);
    }, 1);
</script>

window.print 在 chrome 上同步运行 .. 在控制台中尝试此操作

window.print();
console.log("printed");

除非用户关闭(取消/保存/打印(打印对话框,否则不会显示"打印"。

以下是有关此问题的更详细说明。

我不确定IE或Firefox稍后会检查并更新

请参阅 https://stackoverflow.com/a/15662720/687315。作为一种解决方法,您可以在window.mediaMatch API指示媒体不再匹配"打印"(Firefox和Chrome(后侦听窗口(Firefox和IE(上的afterPrint事件,并侦听文档上的鼠标移动(指示用户已关闭打印对话框并返回到页面(。

请记住,用户可能实际打印了文档,也可能没有实际打印。此外,如果您在 Chrome 中过于频繁地调用window.print(),则甚至可能没有提示用户打印。

你可以检测window.print((何时完成,只需把它放在另一个函数中

//function to call if you want to print
var onPrintFinished=function(printed){console.log("do something...");}
//print command
onPrintFinished(window.print());

在火狐,谷歌浏览器,IE中测试

检测打印是否已完成并关闭打印窗口的最简单方法:

window.onafterprint = function(){ 
  window.onfocus = function(){  
    window.close();
  }
};

这实际上在铬中对我有用。我很惊讶。

jQuery(document).bind("keyup keydown", function(e){
    if(e.ctrlKey && e.keyCode == 80){
         Print(); e.preventDefault();
    }
});

其中 Print 是我编写的一个函数,它调用 window.print((;如果您禁用 Print((,它也可以用作纯阻止程序;

如用户3017502所示

window.print(( 将暂停,以便您可以像这样添加 onPrintFinish 或 onPrintBegin

function Print(){
    onPrintBegin
    window.print();
    onPrintFinish(); 
}

测试了IE,FF,Chrome并适用于所有工作。

    setTimeout(function () { window.print(); }, 500);
    window.onfocus = function () { setTimeout(function () { window.close(); }, 500); }

鉴于您希望等待打印对话框消失,我将在窗口上使用焦点绑定。

print();
var handler = function(){
    //unbind task();
    $(window).unbind("focus",handler);
}
$(window).bind("focus",handler);

通过在处理程序函数中加入取消绑定,我们可以防止焦点事件与窗口保持绑定。

在新窗口中打印,w = window.open(url, '_blank'( 并尝试 w.focus((;w.close((; 并检测页面何时关闭。适用于所有浏览器。

w = window.open(url, '_blank');
w.onunload = function(){
 console.log('closed!');
}
w.focus();
w.print();
w.close();

完成打印后关闭窗口。

它适用于我的$(window(.focus((。

var w;
var src = 'http://pagetoprint';
if (/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())) {
    w = $('<iframe></iframe>');
    w.attr('src', src);
    w.css('display', 'none');
    $('body').append(w);
    w.load(function() {
        w[0].focus();
        w[0].contentWindow.print();
    });
    $(window).focus(function() {
        console.log('After print');
    });
}
else {
    w = window.open(src);
    $(w).unload(function() {
        console.log('After print');
    });
}
我认为

窗口焦点方法是正确的。下面是一个示例,其中我想在隐藏的 iframe 中打开一个 PDF url blob 并打印它。打印或取消后,我想删除 iframe。

/**
 * printBlob will create if not exists an iframe to load
 * the pdf. Once the window is loaded, the PDF is printed.
 * It then creates a one-time event to remove the iframe from
 * the window.
 * @param {string} src Blob or any printable url.
 */
export const printBlob = (src) => {
  if (typeof window === 'undefined') {
    throw new Error('You cannot print url without defined window.');
  }
  const iframeId = 'pdf-print-iframe';
  let iframe = document.getElementById(iframeId);
  if (!iframe) {
    iframe = document.createElement('iframe');
    iframe.setAttribute('id', iframeId);
    iframe.setAttribute('style', 'position:absolute;left:-9999px');
    document.body.append(iframe);
  }
  iframe.setAttribute('src', src);
  iframe.addEventListener('load', () => {
    iframe.contentWindow.focus();
    iframe.contentWindow.print();
    const infanticide = () => {
      iframe.parentElement.removeChild(iframe);
      window.removeEventListener('focus', infanticide);
    }
    window.addEventListener('focus', infanticide);
  });
};

由于打印后的浏览器行为不同,这很困难。桌面版 Chrome 在内部处理打印对话框,因此在打印后不会转移焦点,但是,afterprint事件在这里工作正常(截至目前为 81.0(。另一方面,移动设备上的 Chrome 和大多数其他浏览器在打印后会转移焦点afterprint并且事件在这里无法始终如一地工作。鼠标移动事件在移动设备上不起作用。

因此,检测它是否是桌面浏览器,如果是,请使用印后印事件。如果,请使用基于焦点的检测。您还可以结合使用鼠标移动事件(仅适用于桌面(,以涵盖更多浏览器和更多场景。

好吧,只是为了提醒大家,印后印不会确定打印操作按钮,而是在打印窗口关闭或关闭时执行,取消按钮或 ESC 键关闭打印窗口将考虑印后印,而还没有实际打印发生。

我为与我有相同问题的人提供解决方案。我正在使用Chrome浏览器,在我的项目中,我创建了一个iframe来打印PDF。但是,当我绑定后印事件时,它不起作用。

下面的代码通过绑定焦点事件检测打印是否完成。

  const iframe = document.createElement('iframe');
  iframe.style.display = 'none';
  iframe.src = url;
  iframe.onload = function () {
    console.log('load iframe done')
    const handle = () => {
      window.removeEventListener('focus', handle)
      // do something...
    }
    window.addEventListener('focus', handle)
    iframe.focus()
    iframe.contentWindow.print()
  }
  document.body.appendChild(iframe)

实现 window.onbeforeprint 和 window.onafterprint

window.print(( 之后的 window.close(( 调用在 Chrome v 78.0.3904.70 中不起作用

为了解决这个问题,我使用亚当的答案进行简单的修改:

     function print() {
    (function () {
       let afterPrintCounter = !!window.chrome ? 0 : 1;
       let beforePrintCounter = !!window.chrome ? 0 : 1;
       var beforePrint = function () {
          beforePrintCounter++;
          if (beforePrintCounter === 2) {
             console.log('Functionality to run before printing.');
          }
       };
       var afterPrint = function () {
          afterPrintCounter++;
          if (afterPrintCounter === 2) {
             console.log('Functionality to run after printing.');
             //window.close();
          }
       };
       if (window.matchMedia) {
          var mediaQueryList = window.matchMedia('print');
          mediaQueryList.addListener(function (mql) {
             if (mql.matches) {
                beforePrint();
             } else {
                afterPrint();
             }
          });
       }
       window.onbeforeprint = beforePrint;
       window.onafterprint = afterPrint;
    }());
    //window.print(); //To print the page when it is loaded
 }

我在这里打电话:

<body onload="print();">

这对我有用。请注意,我对这两个函数都使用计数器,以便我可以在不同的浏览器中处理此事件(在 Chrome 中触发两次,在 Mozilla 中触发一次(。要检测浏览器,您可以参考此答案