Окно Javascript.print () в chrome закрытие нового окна или вкладки вместо отмены печати оставляет javascript заблокированным в Родительском окне

в приложении, над которым я работаю, у нас есть несколько разных мест, из которых пользователь может печатать. Во всех этих случаях мы используем один и тот же рабочий процесс открытия нового окна(или вкладки), записывая все, что нам нужно распечатать в документ нового окна, а затем вызываем

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

проблема, которую я вижу, заключается в том, что в Chrome, Если я закрываю вкладку или окно, которое открывается для предварительного просмотра печати, а не нажимаю кнопку отмены, Chrome по-прежнему блокирует javascript на моем родителе окно.

это похоже на проблему, описанную здесь:

Google Chrome блокирует ajax-запросы при открытии предварительного просмотра в дочернем окне

Мы также сталкиваемся с этой проблемой, но я считаю, что это результат того, как мы реализуем печать в новом окне и как работает предварительный просмотр печати Chrome. В IE и Firefox окно печати отображает модальное диалоговое окно, и вы не можете ничего сделать в Родительском окне, пока окно печати закроется. Аналогично chrome блокирует использование родительского окна до отмены предварительного просмотра печати. Однако я ожидал бы, что закрытие этой вкладки или окна будет работать так же, как отмена печати.
Кто имел эту проблему или знает хорошее решение?

спасибо!

9 ответов


похоже, проблема была решена с последним обновлением 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.


проблема в том, что во всплывающем окне есть диалог печати в браузере. Если вы позвоните window.close() сразу же после этого диалог не отображается пользователем. Пользователю необходимо нажать кнопку "Печать"в диалоге. Это не то же самое, что и в других браузерах, где диалог печати является частью ОС и блокирует window.close() пока не уволен-на Chrome, это часть 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();
    }
}

для тех из вас, кто появляется новое окно для печати, а затем автоматически закрывает его после того, как пользователь нажимает "печать" или "отмена" в предварительном просмотре Chrome, я использовал следующее (благодаря помощи от Paulvb's answer):

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


Chrome print обычно является страницей расширения, поэтому на существующей странице нет вложения dom. Вы можете запустить команду print с помощью API командной строки (window.print ()) но тогда они не предоставили API для его закрытия из-за различных причин, таких как выбор параметров печати,печатной машины, подсчета и т. д.


используйте этот код для возврата и перезагрузки текущего окна:

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

Я могу подтвердить, что у меня такая же ошибка в 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();

Если функция 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();

OK вот что сработало для меня! У меня есть кнопка на левом навигаторе. Если вы нажмете на него, он откроет окно, и это окно загрузит документ. После загрузки документа я хочу распечатать документ, а затем немедленно закрыть всплывающее окно.

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

почему это работает?
Ну, после печати вы устанавливаете событие onfocus, чтобы закрыть окно. Всплывающее окно печати загрузится так быстро, что событие onfocus не получит возможности инициировать, пока вы 1) печать 2) отмена печать. Как только вы восстановите фокус на окне, окно будет закрываться!
Я надеюсь, что это сработает для вас


Я mandained некоторые похожие страницы (классическом ASP...)

мой подход состоял в том, чтобы использовать Q promise непосредственно во всплывающем окне.

например, моя проблема заключалась в том, что всплывающее окно, которое я хотел напечатать, слишком быстро закрывалось ... и печать была пуста, я решил так:

звонящий :

var popup = window.open("index.asp","popupwindow","width=800,height=500,left=200,top=5,scrollbars,toolbar=0,resizable");

всплывающее окно (в конце страницы):

<script src="/Scripts/jquery-1.9.1.min.js"></script>
<script src="/Scripts/q.min.js"></script>
<script type="text/javascript">
    Q(window.print()).then(function () {window.close();});
</script>

Я думаю, что ваш "родительский замок" может быть решена подобным образом

Я бы попробовал :

var w = whatever;
Q(
  // fill your popup
).then(function () {
 w.print();
}).then(function () {
 w.close();
}); 

это делает" печать "и" закрытие " асинхронными... таким образом, родитель будет немедленно "разблокирован"