如何检测 window.print()完成

在我的应用程序中,我试图为用户打印一个如下的优惠券页面:

  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

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

176441 次浏览

You can listen to the afterprint event.

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

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

It may be possible to use window.matchMedia to get this functionality in another way.

(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;


}());

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

See https://stackoverflow.com/a/15662720/687315. As a workaround, you can listen for the afterPrint event on the window (Firefox and IE) and listen for mouse movement on the document (indicating that the user has closed the print dialog and returned to the page) after the window.mediaMatch API indicates that the media no longer matches "print" (Firefox and Chrome).

Keep in mind that the user may or may not have actually printed the document. Also, if you call window.print() too often in Chrome, the user may not have even been prompted to print.

You can detect when window.print() is finished simply by putting it in another function

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


//print command
onPrintFinished(window.print());

tested in Firefox,Google chrome,IE

On chrome (V.35.0.1916.153 m) Try this:

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

Works great for me. It will close window after user finished working on printing dialog.

Print in new window with w = window.open(url, '_blank') and try w.focus();w.close(); and detect when page is closed. Works in all browsers.

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

Window close after finish print.

This Actually worked for me in chrome. I was pretty suprised.

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

Where Print is a function I wrote that calls window.print(); It also works as a pure blocker if you disable Print();

As noted here by user3017502

window.print() will pause so you can add an onPrintFinish or onPrintBegin like this

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

compatible with chrome, firefox, opera, Internet Explorer
Note: jQuery required.

<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>

Tested IE, FF, Chrome and works in all.

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

Given that you wish to wait for the print dialog to go away I would use focus binding on the window.

print();


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


$(window).bind("focus",handler);

By putting in the unbind in the handler function we prevent the focus event staying bond to the window.

I think the window focus approach is the correct one. Here is an example in which I wanted to open a PDF url blob in a hidden iframe and print it. After printed or canceled, I wanted to remove the 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);
});
};

window.print behaves synchronously on chrome .. try this in your console

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

"printed" doesn't display unless the print dialog is closed(canceled/saved/printed) by the user.

Here is a more detailed explanation about this issue.

I am not sure about IE or Firefox will check and update that later

Implementing window.onbeforeprint and window.onafterprint

The window.close() call after the window.print() is not working in Chrome v 78.0.3904.70

To approach this I'm using Adam's answer with a simple modification:

     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
}

I'm calling it in here:

<body onload="print();">

This works for me. Note that I use a counter for both functions, so that I can handle this event in different browsers (fires twice in Chrome, and one time in Mozilla). For detecting the browser you can refer to this answer

It works for me with $(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');
});
}

It is difficult, due to different browser behavior after print. Desktop Chrome handles the print dialogue internally, so doesn't shift focus after print, however, afterprint event works fine here (As of now, 81.0). On the other hand, Chrome on mobile device and most of the other browsers shifts focus after print and afterprint event doesn't work consistently here. Mouse movement event doesn't work on mobile devices.

So, Detect if it is Desktop Chrome, If Yes, use afterprint event. If No, use focus based detection. You can also use mouse movement event(Works in desktop only) in combination of these, to cover more browsers and more scenarios.

Simplest way to detect if print has finished and close print window:

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

well, just to remind everyone that the afterprint will not determine the print action button instead it will execute whenever the print window is closed or closing, both cancel button or esc key which closing the print window will consider afterprint while there is no actual print happening yet.