How to detect window.print() finish
在我的应用程序中,我尝试为用户打印出凭证页面,如下所示:
1 2 3 | var htm ="Voucher Details"; $('#divprint').html(htm); window.setTimeout('window.print()',2000); |
"
它起作用,并且打印页面弹出。 但是,一旦用户在浏览器的弹出式打印对话框中单击"
例如,我想在弹出窗口关闭后将用户重定向到另一个页面:
1 | window.application.directtoantherpage();//a function which direct user to other page |
如何确定关闭弹出式打印窗口或何时完成打印?
您可以收听印后事件。
https://developer.mozilla.org/zh-CN/docs/Web/API/window.onafterprint
1 2 3 | window.onafterprint = function(){ console.log("Printing completed..."); } |
可能可以使用window.matchMedia以另一种方式获得此功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | (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)上尝试以下操作:
1 2 3 4 | function loadPrint() { window.print(); setTimeout(function () { window.close(); }, 100); } |
对我来说很棒。用户完成打印对话框后,它将关闭窗口。
与Chrome,Firefox,Opera,Internet Explorer兼容
注意:需要jQuery。
1 2 3 4 5 6 7 8 9 10 | window.onafterprint = function(e){ $(window).off('mousemove', window.onafterprint); console.log('Print Dialog Closed..'); }; window.print(); setTimeout(function(){ $(window).one('mousemove', window.onafterprint); }, 1); |
参见https://stackoverflow.com/a/15662720/687315。解决方法是,您可以在
请记住,用户可能已经或可能没有实际打印过文档。另外,如果您在Chrome中经常调用
window.print在chrome上的行为是同步的。在控制台中尝试
1 2 | window.print(); console.log("printed"); |
除非用户关闭(取消/保存/打印)打印对话框,否则不会显示"已打印"。
这是有关此问题的更详细的说明。
我不确定IE或Firefox稍后是否会检查和更新
您只需将window.print()放入另一个函数中,即可检测出它何时完成
1 2 3 4 5 | //function to call if you want to print var onPrintFinished=function(printed){console.log("do something...");} //print command onPrintFinished(window.print()); |
在Firefox,Google chrome,IE中测试
考虑到您希望等待打印对话框消失,我将在窗口上使用焦点绑定。
1 2 3 4 5 6 7 8 | print(); var handler = function(){ //unbind task(); $(window).unbind("focus",handler); } $(window).bind("focus",handler); |
通过在处理程序函数中加入取消绑定,我们可以防止焦点事件保持与窗口的绑定。
这实际上对我来说适合Chrome。我很惊讶。
1 2 3 4 5 | 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
1 2 3 4 5 | function Print(){ onPrintBegin window.print(); onPrintFinish(); } |
它对我有用$(window).focus()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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'); }); } |
经过IE,FF,Chrome的测试,可以正常运行。
1 2 | setTimeout(function () { window.print(); }, 500); window.onfocus = function () { setTimeout(function () { window.close(); }, 500); } |
使用w = window.open(url,'_blank')在新窗口中打印,然后尝试w.focus(); w.close();并检测页面何时关闭。在所有浏览器中均可使用。
1 2 3 4 5 6 7 | w = window.open(url, '_blank'); w.onunload = function(){ console.log('closed!'); } w.focus(); w.print(); w.close(); |
完成打印后窗口关闭。
您真的不知道用户是否单击了
由于打印后浏览器的行为不同,这很困难。 桌面版Chrome内部处理打印对话框,因此在打印后不会转移焦点,但是
因此,检测它是否为台式机Chrome,
如果是,请使用印后事件。 如果否,请使用基于焦点的检测。 您还可以结合使用鼠标移动事件(仅适用于台式机),以涵盖更多浏览器和更多场景。
我认为窗口聚焦方法是正确的。这是我要在隐藏的iframe中打开PDF网址Blob并进行打印的示例。打印或取消后,我想删除iframe。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /** * 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); }); }; |
实现window.onbeforeprint和window.onafterprint
在Chrome v 78.0.3904.70中window.print()无法使用后的window.close()调用
为了解决这个问题,我使用亚当的答案进行了简单的修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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 } |
我在这里称呼它:
1 | <body onloadx="print();"> |
这对我有用。
请注意,我对这两个功能都使用了计数器,以便可以在不同的浏览器中处理此事件(在Chrome中触发两次,在Mozilla中触发一次)。
要检测浏览器,您可以参考此答案