catch the event of the print from the print dialog box [duplicate] - javascript
In my application, I tried to print out a voucher page for the user like this:
var htm ="<div>Voucher Details</div>";
$('#divprint').html(htm);
window.setTimeout('window.print()',2000);
'divprint' is a div in my page which store information about the voucher.
It works, and the print page pops up. But I want to advance the application once the user clicks 'print' or 'close' in the browser's pop-up print dialog.
For example, I'd like to redirect user to another page after pop up window is closed:
window.application.directtoantherpage();//a function which direct user to other page
How can I determine when the pop up print window is closed or print is finished?
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/
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.
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>
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.
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
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
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();
}
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.
Simplest way to detect if print has finished and close print window:
window.onafterprint = function(){
window.onfocus = function(){
window.close();
}
};
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.
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');
});
}
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);
});
};
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.
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.
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
Related
Determine If Print/Cancel Button in Google Chrome's Print Preview is Clicked
I've been printing my page using the code below: window.print(); An image below is what the print preview in Google chrome browser looks like. It has two main buttons: print and cancel. I want to know if the user has clicked the print or cancel buttons. What I did uses jquery: HTML Code of the Print Preview: <button class="print default" i18n-content="printButton">Print</button> <button class="cancel" i18n-content="cancel">Cancel</button> Jquery Code: $('button > .cancel').click(function (e) { alert('Cancel'); }); $('button > .print').click(function (e) { alert('Print'); }); I tried the code above with no luck. What am I missing?
You can not access Chrome's internal windows (printing dialog in this case) directly from a regular web page. (function () { var beforePrint = function () { alert('Functionality to run before printing.'); }; var afterPrint = function () { alert('Functionality to run after printing'); }; if (window.matchMedia) { var mediaQueryList = window.matchMedia('print'); mediaQueryList.addListener(function (mql) { //alert($(mediaQueryList).html()); if (mql.matches) { beforePrint(); } else { afterPrint(); } }); } window.onbeforeprint = beforePrint; window.onafterprint = afterPrint; }()); Or, If you want to do something when the print preview gets opened, you can try below: $(document).bind("keyup keydown", function (e) { if (e.ctrlKey && e.keyCode == 80) { setTimeout(function () { CallAfterWindowLoad();}, 5000); return true; } }); function CallAfterWindowLoad() { alert("Open and call"); } Reference: How to capture the click event on the default print menu called by Javascript window.print() Maybe if you provide your requirements for this two buttons click event, we can provide you an alternate solution.
it is very easily possible: <body onafterprint="myFunction()"> The myFunction() that you can define within a tag will be fire when either the printing job is done or the cancel button was pressed.
As far as I know, the print preview is not part of any document your JS can access. These might interest you: Detecting browser print event ExtJS 4 - detecting if the user pressed "Print" on the print dialog that was called programatically
<script> window.print(); onafterprint = function () { window.location.href = "index.html"; } </script>
This should do the trick. I've used jQuery v2.2.0 which is included in the html file. $("#print").click(function() { // calls the id of the button that will print document.body.style.visibility = 'hidden'; //code for hiding the body document.getElementById('printthis').style.visibility = 'visible'; // div to be printed document.getElementById('printthis').style.position = 'absolute'; //some code/css for positioning. you can adjust this document.getElementById('printthis').style.top = '40px'; document.getElementById('printthis').style.left = '0px'; if (print()) { // shows print preview. } else { // else statement will check if cancel button is clicked. document.body.style.visibility = 'visible'; document.getElementById('printthis').style.position = ''; document.getElementById('printthis').style.top = ''; document.getElementById('printthis').style.left = ''; alert("Print Canceled"); } }); I guess this might as well be used as a way to print certain divs in your html. Just hide the body element and only show the div that you want to print with some positioning css. Hope it works in yours. I've tried it and I can say that it worked for me.
How to reload scripts after canceling print function in javascript?
So I got this website where I dynamically create elements with javascript. Once a user is done creating the element he wants he can click a print button. This will fire the following javascript function: function printContent() { var restore = document.body.innerHTML; var printcontent = document.getElementById('h').innerHTML; document.body.innerHTML = printcontent; window.print(); document.body.innerHTML = restore; } So far, so good. But when someone cancels the printing it returns visually to its previous state but the scripts are not loaded. I tested this by giving an alert in my external js documents. The alert is never fired when returning from a print command. I know that the problem is the variable restore. It just returns a string. My question: how do I get my js files to reload again while keeping the body of the document in the state of restore when a print command is canceled. Thanks in advance.
There is a window.onafterprint event implemented in firefox and IE, it's not cross-browser though developer.mozilla.org Edit: I found this which should be cross-browser compatible: (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; }());
Javascript setinterval playing all when i get back to window
I have a function applied to setInterval function. When I minimize or change the focused window, then get back to the browser showing my web site, the browser plays everything that happened since i changed the focus to another window, in a very fast manner. Is there a way to hold the animations, setintervals when window of focus in windows change ? Thanks.
I found this post: JavaScript / jQuery: Test if window has focus for me it worked on google chrome but it could be that it doesn't work in some browsers. Here is a fiddle to test: http://jsfiddle.net/ScKbk/ His answer: var window_focus; $(window).focus(function() { window_focus = true; }) .blur(function() { window_focus = false; }); $(document).one('click',function() { setInterval(function() { $('body').append('has focus? ' + window_focus + '<br>'); }, 1000); });
Try this. var handeler; function ShowAnimation() { //SetInterval code handeler = SetInterval(myfunction, 1000); } //clear the handler when not in use. function Clearhandler() { ClearTimeout(handeler); } //call the above method on the onblur event of window. $(window).focus(ShowAnimation(),Clearhandler());
Much like Getu.ch answer except this will only execute your "work" code if the window has focus (runs every 3 seconds). Not tested in all browsers but here is a link showing browser compatibility of window.focus / window.blur (function($) { var windowHasFocus = false; $(window).focus(function() { windowHasFocus = true; }); $(window).blur(function () { windowHasFocus = false; }); setInterval(function() { if(windowHasFocus) { //Do your work } }, 3000); });
How to detect window.print() finish
In my application, I tried to print out a voucher page for the user like this: var htm ="<div>Voucher Details</div>"; $('#divprint').html(htm); window.setTimeout('window.print()',2000); 'divprint' is a div in my page which store information about the voucher. It works, and the print page pops up. But I want to advance the application once the user clicks 'print' or 'close' in the browser's pop-up print dialog. For example, I'd like to redirect user to another page after pop up window is closed: window.application.directtoantherpage();//a function which direct user to other page How can I determine when the pop up print window is closed or print is finished?
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/
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.
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>
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.
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
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
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(); }
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.
Simplest way to detect if print has finished and close print window: window.onafterprint = function(){ window.onfocus = function(){ window.close(); } };
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.
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'); }); }
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); }); };
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.
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.
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
PopUp Blocker code detection not working
I have turned on PopUp blocker in FF and Chrome. I have a piece of code to check PopUp is working as: function checkPopUp() { var myTest = window.open("about:blank","","directories=no,height=1,width=1,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,top=0,location=no"); var popUpsBlocked = ''; if (!myTest) { popUpsBlocked = true; } else { popUpsBlocked = false; } return popUpsBlocked; } its working fine "onload" of the page. But when i am using it with hyper link onclick, its not working a popup is getting opened. <a onclick="checkPopUp()" href="#">Test</a>
Browsers allow popups during "click" event loops. Different browsers have different configuration options under user control, but generally the default behavior is that a "click" is treated as a user willingly requesting functionality from a page.
The below code has been tested in FF29.0, IE9, Chrome35.0, Safari and the best part is it is working!!! var popupBlocker = { isPopupBlocked: function (width, height) { setTimeout(function () { var popup = window.open(""); if (!popup) { return false; } else { popup.document.open(); popup.document.write("<html><body onload='window.close();'></body></html>") popup.document.close(); return true; } }, 100); } }; popupBlocker.isPopupBlocked();