您好,我在 Safari 中遇到了一个奇怪的问题。我有一个按钮,单击它会打印 html 的内容。我的问题是当打电话时window.print()
第一次它工作得很好,但是,在第二次单击时,它会显示一个弹出窗口,说明:
'此网页正在尝试打印。您想打印该网页吗?
如果我点击Print在此对话框中什么也没有发生。有什么想法为什么会发生这种情况吗?先感谢您!
JavaScript -
$scope.print = function() {
var contents = document.getElementById("print-section").outerHTML;
var frame1 = document.createElement('iframe');
frame1.name = "frame3";
frame1.style.position = "absolute";
frame1.style.top = "-1000000px";
document.body.appendChild(frame1);
var frameDoc = frame1.contentWindow ? frame1.contentWindow : frame1.contentDocument.document ? frame1.contentDocument.document : frame1.contentDocument;
frameDoc.document.open();
frameDoc.document.write('<html><head>'); // add some libraries for the new document
frameDoc.document.write('</head><body>');
frameDoc.document.write(contents);
frameDoc.document.write('</body></html>');
frameDoc.document.close();
setTimeout(function () {
window.frames["frame3"].focus();
window.frames["frame3"].print();
document.body.removeChild(frame1);
}, 500);
return false;
};
Html-
<div id="print-section">
<div>Section to print<>
</div>
正如 Matteo Conta 正确提到的,问题在于 Safari 的打印确认对话框不会停止 JS 代码执行流程以等待打印。
因此,我们真正想要的是检测打印操作何时结束,以便绝对安全地运行清理。
setTimeout
解决方案是一个很好的起点,但我想更可靠地解决问题,并提出了一个基于事件的解决方案,使用matchMedia
and onfocus
捕捉打印完成(取消或完成)的确切时刻。
下面是我针对这个特定问题测试过的代码(ES5,iframe 打印)。
另外,我还创建了GitHub 上的要点 https://gist.github.com/capturetheflag/a588f4d5919efebf2eae315aeb9e2297并展示了通用方法。希望它会有用。
$scope.print = function () {
var frame = appendFrame();
// Safari
if (!window.onafterprint) {
// emulate onbeforeprint/onafterprint events
var mediaQueryCallback = function (mql) {
if (!mql.matches && frame) {
document.body.removeChild(frame);
}
};
var mediaQueryList = window.frames[frame.name].matchMedia('print');
mediaQueryList.addListener(mediaQueryCallback);
// the code below will trigger a cleanup in case a user hits Cancel button
// in that Safari's new additional print confirmation dialog
window.frames[frame.name].focus();
window.frames[frame.name].onfocus = function () {
return mediaQueryCallback(mediaQueryList);
};
}
window.frames[frame.name].print();
return false;
};
为了简洁起见,我将框架创建代码提取到一个简单的函数中(appendFrame
) 并省略setTimeout
从原始问题调用(之后frameDoc.document.close();
line).
var appendFrame = function () {
var contents = document.getElementById("print-section").outerHTML;
var frame1 = document.createElement('iframe');
frame1.name = "frame3";
frame1.style.position = "absolute";
frame1.style.top = "-1000000px";
document.body.appendChild(frame1);
var frameDoc = frame1.contentWindow ? frame1.contentWindow : frame1.contentDocument.document ? frame1.contentDocument.document : frame1.contentDocument;
frameDoc.document.open();
frameDoc.document.write('<html><head>'); // add some libraries for the new document
frameDoc.document.write('</head><body>');
frameDoc.document.write(contents);
frameDoc.document.write('</body></html>');
frameDoc.document.close();
return frame1;
};
灵感来自 MDN 文章:
onbeforeprint https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeprint
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)