【问题标题】:Firefox won't print unless I set a breakpoint?除非我设置断点,否则 Firefox 不会打印?
【发布时间】:2017-06-21 14:20:13
【问题描述】:

我有一个创建 iframe 的方法,将文本框的内容复制到该 iframe,打印 iframe,然后删除 iframe:

function CentralPrint(controlID)
{
    var frameSet = document.createElement('iframe');

    frameSet.name = "frameSet";
    frameSet.id = "ErrorReportPrintingFrame";
    frameSet.style.position = "absolute";
    frameSet.style.top = "-1000000px";
    document.body.appendChild(frameSet);

    var frameDoc = frameSet.contentWindow ? frameSet.contentWindow : frameSet.contentDocument.document ? frameSet.contentDocument.document : frameSet.contentDocument;
    frameDoc.document.open();

    var content = document.getElementById(controlID).value.replace(/\n/gi, '<br>');

    frameDoc.document.write('<html><head><title></title><table><tr><td>');
    frameDoc.document.write(' <style type="text/css"> table tr td { font-family: Arial,Helvetica,sans-serif; } </style> </head><body>');
    frameDoc.document.write(content);
    frameDoc.document.write('</td> </tr> </table> </body></html>');

    frameDoc.document.close();

    var iframe = document.getElementById("ErrorReportPrintingFrame");
    var result = iframe.contentWindow.document.execCommand("print", false, null);

    if (!result)
    {
        iframe.contentWindow.print();
    }

    document.body.removeChild(frameSet);

    return false;
}

这适用于 IE 11、Chrome,它适用于 Firefox 如果我设置了一个断点并单步执行代码。

我认为这无关紧要,但是当我使用 IE 和 Chrome 逐步执行此操作时,resulttrue,而在 Firefox 中,resultfalse

不过,除非我在 Firefox 中设置断点,否则我不会弹出选择我的打印设备的弹出窗口。

知道是什么原因造成的吗?

【问题讨论】:

  • 我看到了这个答案:stackoverflow.com/a/25323486/4065876。也许有帮助。
  • @JoseLuis 是的,这就是我得到result 的原因。如果它是错误的,那么我调用print() 而不是execCommand,如最后一个要点here 中所述
  • 哦,对不起! :-(

标签: javascript iframe printing


【解决方案1】:

我找到了解决方案,但为什么它解决了这个问题,我无法理解:

function CentralPrint(controlID)
{
    // New variable
    var isFirefox = typeof InstallTrigger !== 'undefined';

    var frameSet = document.createElement('iframe');

    frameSet.name = "frameSet";
    frameSet.id = "ErrorReportPrintingFrame";
    frameSet.style.position = "absolute";
    frameSet.style.top = "-1000000px";
    document.body.appendChild(frameSet);

    var frameDoc = frameSet.contentWindow ? frameSet.contentWindow : frameSet.contentDocument.document ? frameSet.contentDocument.document : frameSet.contentDocument;
    frameDoc.document.open();

    var content = document.getElementById(controlID).value.replace(/\n/gi, '<br>');

    frameDoc.document.write('<html><head><title></title><table><tr><td>');
    frameDoc.document.write(' <style type="text/css"> table tr td { font-family: Arial,Helvetica,sans-serif; } </style> </head><body>');
    frameDoc.document.write(content);
    frameDoc.document.write('</td> </tr> </table> </body></html>');

    frameDoc.document.close();

    // Use a timeout function instead of just issuing the command immediately
    setTimeout(function ()
    {
        var iframe = document.getElementById("ErrorReportPrintingFrame");

        if (isFirefox != true)
            iframe.contentWindow.document.execCommand("print", false, null);
        else
            iframe.contentWindow.print();

        document.body.removeChild(frameSet);
    }, 500);

    return false;
}

我想在打印命令执行它需要做的事情之前删除元素一定是一些奇怪的问题?

【讨论】:

    【解决方案2】:

    此类问题称为race condition。您正在尝试在元素完成加载之前获取它。

    您可以将onLoad 事件侦听器添加到frameSet,而不是使用超时。

    frameSet.onload = function() {
      var iframe = document.getElementById("ErrorReportPrintingFrame");
      ...
    };
    

    或者,如果您喜欢超时,您很可能可以将其减少到 0,它仍然可以工作。

    【讨论】:

    • 这对我不起作用。我尝试将其分配给frameDoc,但这也不是。我还将document.body.appendChild(frameSet); 行移动到尝试打印之前执行的最后一件事,我认为它可能是在实际写入内容之前尝试打印。控制台告诉我TypeError: frameSet.contentDocument is null
    • FireFox 有一些竞争条件错误,通常可以使用 setTimeout 0 解决。如果是浏览器中的错误,可能是您唯一的选择
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2018-12-21
    • 2016-05-28
    • 2019-05-07
    相关资源
    最近更新 更多