web-dev-qa-db-ja.com

chromeのJavascript window.print()、印刷をキャンセルする代わりに新しいウィンドウまたはタブを閉じると、javascriptが親ウィンドウでブロックされたままになる

私が取り組んでいるアプリケーションには、ユーザーが印刷できるさまざまな場所があります。これらのすべての場合において、新しいウィンドウ(またはタブ)を開く、同じワークフローを使用して、新しいウィンドウのドキュメントに印刷するために必要なものをすべて書き、それから呼び出します

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

私が見ている問題は、Chromeで、キャンセルボタンをクリックする代わりに印刷プレビュー用に開いているタブまたはウィンドウを閉じると、Chromeが親ウィンドウのjavascriptをブロックしていることです。

ここで説明する問題に似ています。

Google Chromeは、子ウィンドウで印刷プレビューを開いたときにajaxリクエストをブロックします

この問題も発生していますが、これは、新しいウィンドウでの印刷の実装方法と、Chromeの印刷プレビューの動作方法の結果であると考えています。 IEおよびFirefoxでは、印刷ウィンドウにモーダルダイアログが表示され、印刷ウィンドウを閉じるまで親ウィンドウでは何もできません。同様に、chromeは、印刷プレビューがキャンセルされるまで親ウィンドウの使用をブロックしています。ただし、そのタブまたはウィンドウを閉じると、印刷をキャンセルするのと同じように動作するはずです。
他に誰かがこの問題を抱えていたり、良い解決策を知っていますか?

ありがとうございました!

46
umitelight

最新のChromeアップデートで問題が解決されたようです... Chromeバージョン36.0.1964.4 dev-mを実行しています。

次の操作を行って、ユーザーに印刷プレビューウィンドウを閉じないように警告することも制限されていました。

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

これで、Chrome更新後に警告が表示されなくなりました。

21
Paul VB

問題は、ポップアップウィンドウ内にブラウザー内の印刷ダイアログがあることです。 window.close()をすぐに呼び出すと、ダイアログはユーザーに表示されません。ユーザーはダイアログ内の「印刷」をクリックする必要があります。これは、印刷ダイアログがOSの一部である他のブラウザとは異なり、window.close()がブロックされるまでブロックされます。Chromeでは、OSではなくChromeの一部です。

これは、親ウィンドウによって作成された小さなポップアップウィンドウで使用したコードです。

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();
    }
}
5
Coder

印刷する新しいウィンドウをポップアップし、ユーザーがChrome印刷プレビューで[印刷]または[キャンセル]をクリックした後、自動的にウィンドウを閉じる場合は、次を使用しました(ありがとうPaulVBの答えからの助け):

if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    var showPopup = false;
    window.onbeforeunload = function () {
        if (showPopup) {
            return 'You must use the Cancel button to close the Print Preview window.\n';
        } else {
            showPopup = true;
        }
    }
    window.print();
    window.close();
} else {
    window.print();
    window.close();
}

また、Chromeのバージョンでフィルタリングすることをお勧めしますか...

1
Primalpat

通常、Chrome印刷は拡張ページであるため、既存のページでdom添付ファイルは発生しません。コマンドラインapis(window.print())を使用して印刷コマンドをトリガーできますが、印刷オプション、印刷機、カウントなどを選択するなど、さまざまな理由でそれを閉じるためのAPIを提供していません。

0
Venkatesh Nadar

OKここで私のために働いたものです!左ナビゲーションにボタンがあります。クリックするとウィンドウが開き、そのウィンドウにドキュメントが読み込まれます。ドキュメントを読み込んだ後、ドキュメントを印刷して、すぐにポップアップウィンドウを閉じます。

contentDiv.focus();
contentDiv.contentWindow.print();
contentDiv.contentWindow.onfocus = function() {
    window.close();
};

なぜ機能したのですか?
まあ、印刷後、ウィンドウを閉じるようにonfocusイベントを設定します。印刷ポップアップは非常に高速でロードされるため、1)印刷2)印刷をキャンセルするまで、onfocusイベントはトリガーする機会を得られません。ウィンドウにフォーカスを戻すと、ウィンドウが閉じます!
それがあなたのために働くことを願っています

0
AhmedGadir

このコードを実行すると、Googleプリントサービスのポップアップが開きます。

function openPrint(x) {

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

}

Xが整数であるコンソールで試してください。

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

ありがとう

0
Siddharth

Windows 7でChromeバージョン35を使用して同じバグがあることを確認できますが、Chromeで新しいタブを開いてダイアログを表示している部分的なソリューションを共有します。

他のブラウザでは、ユーザーがキャンセルをクリックすると、新しい印刷ウィンドウが自動的に閉じます。

//Chrome's versions > 34 is some bug who stop all javascript when is show a prints preview
//http://stackoverflow.com/questions/23071291/javascript-window-print-in-chrome-closing-new-window-or-tab-instead-of-cancel
if(navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
    var popupWin = window.open();
    popupWin.window.focus();
    popupWin.document.write('<!DOCTYPE html><html><head>' +
        '<link rel="stylesheet" type="text/css" href="style.css" />' +
        '</head><body onload="window.print()"><div class="reward-body">' + printContents + '</div></html>');
    popupWin.onbeforeunload = function (event) {
        return 'Please use the cancel button on the left side of the print preview to close this window.\n';
    };
}else {
    var popupWin = window.open('', '_blank', 'width=600,height=600,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
    popupWin.document.write('<!DOCTYPE html><html><head>' +
        '<link rel="stylesheet" type="text/css" href="style.css" />' +
        '</head><body onload="window.print()"><div class="reward-body">' + printContents + '</div>' +
        '<script>setTimeout(function(){ window.parent.focus(); window.close() }, 100)</script></html>');
}
popupWin.document.close();
0
Eduardo Chavira

次のコードを使用して、現在のウィンドウを返し、再読み込みします。

function printpost() {
  if (window.print()) {
    return false;
  } else {
    location.reload();
  }
}
0

SetTimeout関数も機能しない場合は、次を実行します。

//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();
0
Daybreak