safari不允许第二个window.print()

问题描述 投票:6回答:2

您好我在Safari中遇到了一个奇怪的问题。我有一个按钮,当点击它打印html的内容。我的问题是,当第一次调用window.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>
javascript html printing safari
2个回答
2
投票

经过一番调查,我找到了解决方案。

仅当您“取消”打印时,Safari才会显示打印警告。但是,第二次空白打印的原因是您使用了太快的内容删除

document.body.removeChild(frame1)

如果将等待时间从500毫秒增加到5秒,则可以让用户有时间关闭警告弹出窗口并进行打印。

在我的情况下,我成功测试了Chrome / FF / Edge / Safari这个jQuery插件,在这个库中也增加了删除超时qazxsw poi


0
投票

正如Matteo Conta正确提到的,问题是Safari的打印确认对话框不会阻止JS代码执行流程等待打印。 因此,我们真正想要的是检测打印操作的确切时间,以便绝对安全地运行清理。

https://github.com/DoersGuild/jQuery.print解决方案是一个很好的起点,但我想更可靠地解决问题,并提出了一个基于事件的解决方案,使用setTimeoutmatchMedia来捕捉打印完成(取消或完成)的确切时刻。

下面是我为这个特定问题(ES5,iframe打印)测试过的代码。 此外,我已经使用通用方法创建了onfocus。希望它会有用。

a Gist on GitHub

为简洁起见,我将框架创建代码提取为一个简单的函数($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();

受MDN文章的启发:

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

© www.soinside.com 2019 - 2024. All rights reserved.