Javascript window.print() in chrome, closing new window or tab instead of cancelling print leaves javascript blocked in parent window

116,513

Solution 1

It looks like the problem had been resolved with the latest Chrome update... I'm running the Chrome Version 36.0.1964.4 dev-m.

I was limited too warning the user from closing print preview window by doing the following:

if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1){   // Chrome Browser Detected?
    window.PPClose = false;                                     // Clear Close Flag
    window.onbeforeunload = function(){                         // Before Window Close Event
        if(window.PPClose === false){                           // Close not OK?
            return 'Leaving this page will block the parent window!\nPlease select "Stay on this Page option" and use the\nCancel button instead to close the Print Preview Window.\n';
        }
    }                   
    window.print();                                             // Print preview
    window.PPClose = true;                                      // Set Close Flag to OK.
}

Now the warning is no longer coming up after the Chrome update.

Solution 2

The problem is that there is an in-browser print dialogue within the popup window. If you call window.close() immediately then the dialogue is not seen by the user. The user needs to click "Print" within the dialogue. This is not the same as on other browsers where the print dialogue is part of the OS, and blocks the window.close() until dismissed - on Chrome, it's part of Chrome, not the OS.

This is the code I used, in a little popup window that is created by the parent window:

var is_chrome = function () { return Boolean(window.chrome); }
window.onload = function() {
    if(is_chrome){
        /*
         * These 2 lines are here because as usual, for other browsers,
         * the window is a tiny 100x100 box that the user will barely see.
         * On Chrome, it needs to be big enough for the dialogue to be read
         * (NB, it also includes a page preview).
        */
        window.moveTo(0,0);
        window.resizeTo(640, 480);

        // This line causes the print dialogue to appear, as usual:
        window.print();

        /*
         * This setTimeout isn't fired until after .print() has finished
         * or the dialogue is closed/cancelled.
         * It doesn't need to be a big pause, 500ms seems OK.
        */
        setTimeout(function(){
            window.close();
        }, 500);
    } else {
        // For other browsers we can do things more briefly:
        window.print();
        window.close();
    }
}

Solution 3

In order to work around this problem, I had to switch the printing process from a new window to a hidden iframe. The iframe remains in the DOM and is reused for additional printing (receipts in our case).

Inspired by Daybreaks's answer https://stackoverflow.com/a/39099832/373521

function printHtml(html) {
    try {
        var iframe = document.getElementById("printingFrame");
        if (!iframe) {
            iframe = document.createElement('iframe');
            iframe.id = "printingFrame";
            iframe.name = "printingFrame";
            iframe.width = '0';
            iframe.height = '0';
            iframe.style = 'position: absolute;top: 0;left: 0;width: 0;height: 0;';
            document.body.appendChild(iframe);
        }

        iframe.contentWindow.document.open();
        iframe.contentWindow.document.write('<!DOCTYPE html');
        iframe.contentWindow.document.write('<html><head>');
        iframe.contentWindow.document.write(
            '<style type="text/css">' +
            'body{font-family:Verdana, Arial;font-size:12px;}' +
            '@media all {.page-break { display: none; }}' +
            '@media print {.page-break { display: block; page-break-before: always; }}' +
            '</style>');
        iframe.contentWindow.document.write('</head><body>');
        iframe.contentWindow.document.write(html);
        iframe.contentWindow.document.write('</body></html>');
        iframe.contentWindow.document.close();

        window.frames["printingFrame"].focus();
        window.frames["printingFrame"].print();
    } catch (ex) {
        console.error("Error printing: " + ex.message);
    }
}



Solution 4

If the setTimeout function does not work for you either, then do the following:

//Create an iframe
iframe = $('body').append($('<iframe id="documentToPrint" name="documentToPrint" src="about:blank"/>'));
iframeElement = $('#documentToPrint')[0].contentWindow.document;

//Open the iframe
iframeElement.open();

//Write your content to the iframe
iframeElement.write($("yourContentId").html());

//This is the important bit.
//Wait for the iframe window to load, then print it.
$('#documentToPrint')[0].contentWindow.onload = function () {
    $('#print-document')[0].contentWindow.print();
    $('#print-document').remove();
};
iframeElement.close();

Solution 5

Run this code It will open google print service popup.

function openPrint(x) {

   if (x > 0) { 
       openPrint(--x); print(x); openPrint(--x);
   }

}

Try it on console where x is integer .

openPrint(1);   // Will open Chrome Print Popup Once
openPrint(2);   // Will open Chrome Print Popup Twice after 1st close and so on

Thanks

Share:
116,513

Related videos on Youtube

umitelight
Author by

umitelight

Updated on April 28, 2021

Comments

  • umitelight
    umitelight about 3 years

    In the application I work on, we have several different places a user can print from. In all these cases we are using the same workflow of opening a new window(or tab), writing whatever we need to print to the document of the new window, and then we call

        $(w.document).ready(function () {
            w.focus();
            w.print();
            w.close();
        });  
    

    The issue I'm seeing is that in Chrome, if I close the tab or window that is opened for the print preview instead of clicking the cancel button, Chrome is still blocking the javascript on my parent window.

    It is similar to the issue described here:

    Google Chrome blocks ajax requests when print preview is opened on child window

    We are experiencing this issue as well, but I believe this is a result of how we are implementing printing in a new window and the way Chrome's print preview works. In IE and Firefox, the print window displays the modal dialog, and you are not able to do anything in the parent window until the print window is closed. Similarly chrome is blocking use of the parent window until the print preview is cancelled. However I would expect closing that tab or window to work the same as cancelling the print.
    Has anyone else had this issue or know of a good solution?

    Thank you!

    • ReLeaf
      ReLeaf about 10 years
      Could you use this solution stackoverflow.com/questions/805463/… to detect when the user closes the window and if so, fire your w.close event?
    • umitelight
      umitelight about 10 years
      @ReLeaf Thanks for the response. I added the suggested binding, $(w).bind("beforeunload", function () { w.close(); }); This does get fired when I close the print tab/window, but w.close() does not "cancel" the print preview. Chrome is still blocking any actions in the javascript of my parent window. In the print preview, there's an option to use the system dialog, and if close that dialog, it does cancel the print and my parent window returns to normal. I either need to programmatically use the system dialog or "cancel" printing. I have not been able to find a solution to either.
    • ReLeaf
      ReLeaf about 10 years
      That's a bummer. I'll look around for a way to fire the cancel button and see what I can come up with. Update back here if you find a solution.
    • Malk
      Malk about 10 years
      I am watching this question; I hope someone comes up with an answer. I have submitted an issue to Google, but if someone can come up with a workaround until it's fixed it would be great. Here is a relevant fiddle: jsfiddle.net/6yd25/show
    • John Sanders
      John Sanders about 10 years
      I'm on a Mac (Mavericks), using Chrome 34.0.1847.116, and this bug doesn't seem to be present. Your fiddle demo works for me.
    • Sheepy
      Sheepy about 10 years
      I concur with John. I am using Chrom 34 on Windows 8 and cannot reproduce the issue, neither can I find related bug in Chrome's bug database.
    • Henrik Janbell
      Henrik Janbell about 10 years
      I can confirm that the issue remains in Chrome 34 on Windows 7, I've got the same setup as described in the question.
    • umitelight
      umitelight about 10 years
      I haven't yet been able to verify it working on windows 8, but I did verify that it does work for a Mac, however it looks like the Mac print preview window is different from the one in windows 7 because you can see the 'Print'/'Cancel' buttons are switched. So maybe they have it fixed in some instances of the print preview window, but have yet to update it for windows 7. Hopefully it is resolved soon, as most of the users of our application use windows 7 or earlier and this is a potential workflow that crashes our application.
    • simdrouin
      simdrouin about 10 years
      I have the exact same issue on Windows 8, using Chrome 34
    • jValdron
      jValdron about 10 years
      I can confirm this on Chrome 34 on Windows 8, I've tried Canary build v36, and it works fine. For the moment being, I've added a check for version less than 36, just add a onbeforeunload that warns the user.
    • Brams
      Brams about 10 years
      Did anyone find a solution for this? I find it hard to believe that we would have to wait for a chrome update to resolve the issue. I'm sure there's something that can be done programatically...right?
  • umitelight
    umitelight about 10 years
    Thanks for the update on chrome v36, I checked that out and did confirm this issue is fixed in that version, so it appears the best we can do for now is a warning like you suggested.
  • jgerman
    jgerman almost 10 years
    We can't force our end users to update to the v36 Beta version of Chrome. Thank you for the JS code. This worked perfectly!
  • Stijnvdk
    Stijnvdk almost 10 years
    Chrome 36.0.1985.125 has now been promoted into the stable channel
  • SearchForKnowledge
    SearchForKnowledge over 9 years
    I open a new window with some text and have a print button. It works fine in Chrome but not in IE10 :/
  • Goddard
    Goddard over 4 years
    On version 78 and the print dialog is still blocking
  • Jacob Weisenburger
    Jacob Weisenburger about 3 years
    On Chrome Version 90.0.4430.85 and the print dialog is still blocking
  • Jerod Houghtelling
    Jerod Houghtelling about 3 years
    I think it problem just came back on Version 90.0.4430.85! We are scrambling to get a fix as it's killing our application when the user used the close button.
  • Beginner
    Beginner about 3 years
    @JerodHoughtelling, yes mine too, did you fixed that?
  • Jerod Houghtelling
    Jerod Houghtelling about 3 years
    @Beginner I have posted my answer as it was too long to share in a comment. stackoverflow.com/a/67283771/373521