Подтвердить что ты не робот

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

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

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

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

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

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

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

Спасибо!

4b9b3361

Ответ 1

Похоже, проблема была решена с последним обновлением Chrome... Я запускаю версию версии 36.0.1964.4 для Chrome.

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

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 больше не появляется.

Ответ 2

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

Ответ 3

Для тех из вас, кто выдает новое окно для печати, а затем автоматически закрывает его после того, как пользователь нажимает "Печать" или "Отмена" в предварительном просмотре печати 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...

Ответ 4

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

Ответ 5

Я могу подтвердить, что у меня такая же ошибка в Windows 7 с помощью Chrome Версии 35, но я разделяю свое частное решение, открывающее новую вкладку в Chrome и показывающее диалог.

Для другого браузера, когда пользователь нажимает кнопку "Отмена", автоматически закрывает новое окно печати. ​​

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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

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

Ответ 9

Я заказал некоторую подобную страницу (классический asp...)

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

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

Caller:

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

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