在我工作的应用程序中,用户可以从几个不同的地方进行打印。在所有这些情况下,我们都使用相同的工作流程,打开一个新窗口(或选项卡),将需要打印的内容写入新窗口的文档,然后我们称之为
$(w.document).ready(function () {
w.focus();
w.print();
w.close();
});
我看到的问题是,在Chrome中,如果我关闭为打印预览打开的选项卡或窗口,而不是单击取消按钮,Chrome仍然会阻止我的父窗口上的javascript。
它与此处描述的问题类似:
当在子窗口上打开打印预览时,Google Chrome会阻止ajax请求
我们也遇到了这个问题,但我相信这是我们如何在新窗口中实现打印以及Chrome打印预览工作方式的结果。在IE和Firefox中,打印窗口显示模式对话框,在关闭打印窗口之前,您无法在父窗口中执行任何操作。类似地,chrome会阻止使用父窗口,直到取消打印预览。但是,我希望关闭该选项卡或窗口的工作方式与取消打印的工作方式相同。
其他人有没有遇到过这个问题,或者知道一个好的解决方案?
谢谢!
看起来问题已经通过最新的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 thenCancel 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();
}
}
为了解决这个问题,我不得不将打印过程从一个新窗口切换到一个隐藏的iframe。iframe保留在DOM中,并可用于其他打印(在我们的例子中是收据)。
灵感来自Daybreaks的答案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);
}
}
如果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();
对于那些弹出一个新窗口进行打印,然后在用户点击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版本进行过滤。。。
运行此代码将打开谷歌打印服务弹出窗口。
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
感谢
好吧,这就是对我有效的方法!我的左Nav上有一个按钮。如果单击它,它将打开一个窗口,该窗口将加载一个文档。加载文档后,我想打印文档,然后立即关闭弹出窗口。
contentDiv.focus();
contentDiv.contentWindow.print();
contentDiv.contentWindow.onfocus = function() {
window.close();
};
为什么这样做
好吧,打印完成后,您将onfocus事件设置为关闭窗口。打印弹出窗口将加载得如此之快,以至于在您1)打印2)取消打印之前,无法触发对焦事件。一旦你重新聚焦在窗口上,窗口就会关闭!
我希望这对你有效
Chrome打印通常是一个扩展页面,所以在你现有的页面中没有dom附件。您可以使用命令行api(window.print())触发打印命令,但由于选择打印选项、打印机器、计数等原因,他们没有提供关闭命令的api
function printpost() {
if (window.print()) {
return false;
} else {
location.reload();
}
}
我可以确认我在使用Chrome版本35的Windows 7上也有同样的错误,但我分享了我的部分解决方案,即在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();
我制作了一些类似的页面(经典的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();
});
这使得"打印"one_answers"关闭"异步。。。因此父级将立即"解锁"