打印对话框关闭后自动关闭窗口

110

当用户点击按钮时,我会打开一个标签页。在 onload 事件中,我会弹出打印对话框,但用户问我是否有可能在将数据发送到打印机打印后,自动关闭该标签页。我不确定是否可以实现这一点。我尝试过使用 setTimeout();,但由于用户可能会分心并重新打开标签页,所以这不是一个可靠的方法。是否有任何办法可以实现这个功能?


40个回答

141

如果在调用print()后立即尝试关闭窗口,可能会立即关闭窗口并且print()将不起作用。这是不应该做的事情

如果您在调用print()之后立即尝试关闭窗口,则可能会导致程序出现异常,因此需要避免这种行为。

window.open();
...
window.print();
window.close();

这个解决方案可以在Firefox中运行,因为在调用print()时,它会等待打印完成,然后继续处理JavaScript并关闭窗口。

IE将失败,因为它在不等待print()调用完成的情况下调用close()函数。弹出窗口将在打印完成之前关闭。

解决方法之一是使用“onafterprint”事件,但我不建议您这样做,因为这些事件只适用于IE。

最佳方式是在打印对话框关闭(打印完成或取消)后关闭弹出窗口。此时,弹出窗口将聚焦,并且您可以使用“onfocus”事件关闭弹出窗口。

要实现这一点,只需将此JavaScript嵌入代码插入到您的弹出窗口中:

<script type="text/javascript">
window.print();
window.onfocus=function(){ window.close();}
</script>

希望这有帮助 ;-)

更新:

对于新的Chrome浏览器,它可能仍然关闭得太快,请参见此处。我已经实施了这个更改,并且适用于所有当前浏览器:2/29/16。

        setTimeout(function () { window.print(); }, 500);
        window.onfocus = function () { setTimeout(function () { window.close(); }, 500); }

17
目前看来这似乎对Chrome不起作用,因为Chrome在打印时会自行处理,所以当打印对话框加载时窗口不会失去焦点,因此在打印完成后也不会重新获得焦点。有没有办法让它在Chrome上工作? - jlbriggs
6
截至2016年2月,这个基于focus()的回答以及其他所有基于focus()的回答,在Chrome浏览器中都已经无效了。唯一有效的解决方案是@noamtcohen提供的(很遗憾它的投票数很低)。 - Jpsy
3
我认为Chrome最新版本在页面加载图片之前不会显示打印对话框,但它会在关闭前执行,所以页面在加载之前就关闭了(打印对话框从未显示)。为解决这个问题,请将window.onload = function() { window.print(); setTimeout(window.close, 500); };修改为: - Brian Leishman
11
以上解决方案已经不再有效,请添加事件监听器 onafterprint 以关闭窗口。代码:window.onafterprint = function(){ window.close()}; - Rahat Hameed
3
今年是2022年,onafterprint现在被所有主要浏览器支持,并且是最简单的解决方案。 - Michael T
显示剩余8条评论

101

这是我想到的,我不知道为什么在关闭之前会有一个小延迟。

 window.print();
 setTimeout(window.close, 0);

1
有趣的是,这个评分低的答案目前是正确的。 截至2016年2月,基于focus()的答案在Chrome中已经不再起作用。 这个解决方案适用于Windows和OS X上的FF、Chrome和Safari,IE9+、Android Chrome和IOS Safari。我们只在旧版IE中遇到了确认对话框。其他所有关闭都是无缝的。 - Jpsy
7
截至3月17日,我在谷歌浏览器(版本56)上尝试了这个方法,但它并没有完全奏效,不过稍微增加一些超时时间就可以了。具体操作为:输入 window.print(); 然后添加代码 setTimeout(window.close, 500); - jAC
正如jAC所提到的,这需要更多时间才能使其工作。在我的电脑上,10毫秒不够,但是100毫秒就可以了。看起来这取决于呈现打印预览所需的时间。当我将它设置为10毫秒时,它只打印了页面的部分呈现版本。而当我设置为100毫秒时,整个页面都被打印出来了。 - Jacob Ewing
2
进一步说,似乎在MacBook上的Chrome浏览器中,一旦打印窗口完全呈现出来,超时就会暂停,并在关闭窗口后计算剩余时间。 - Jacob Ewing
1
你不需要输入0,因为它是默认值。 - Brian Leishman

41

确保解决此问题的最简单方法是执行以下操作:

      <script type="text/javascript">
         window.onafterprint = window.close;
         window.print();
      </script>

或者,如果你想做一些事情,例如返回上一页。

    <script type="text/javascript">
        window.print();
        window.onafterprint = back;

        function back() {
            window.history.back();
        }
    </script>

window.close(); - Mustafa
注意:window.onafterprint = window.close(); 应该改为 window.onafterprint = window.close;。前者将 window.close()结果分配给 onafterprint。这会导致在设置处理程序时立即运行 window.close(),并且在引发 onafterprint 事件时不运行任何内容。后者将 window.close 分配为事件处理程序,这正是我们想要的。 - Kei
2
此外,在某些浏览器中,当执行 window.print(); 后,代码执行会暂停直到打印对话框被关闭。当发生这种情况时,可能会在分配 onafterprint 之前引发 onafterprint 事件。因此,最好将 window.onafterprint = window.close; 放在 window.print(); 之前。否则,与其他答案提供的基于 onfocus 或 setTimeout 的方法相比,本答案中使用的方法效果更好。 - Kei
注意:现代浏览器已经支持此功能,请参考https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onafterprint#browser_compatibility中的兼容性图表。 - Blaise

14

只是:

window.print();
window.close();

它有效。


2
这在我的Chrome浏览器上不可靠。有时它可以工作,但有时窗口在打印对话框出现之前就立即关闭了。我可以通过将超时时间增加到5000来防止发生这种情况,但是在打印后有时需要长达5秒钟才能关闭窗口。我不确定这里发生了什么,但它似乎不太可能在不同的浏览器中都表现良好。 - speedarius
1
如下所述,完整的跨浏览器解决方案更为复杂。 - Eric Rini
1
不要忘记警告:“脚本只能关闭由它打开的窗口。” - Cas Bloem
以上解决方案已经不再适用,请添加事件监听器 onafterprint 来关闭窗口。window.onafterprint = function(){ window.close()}; - Rahat Hameed

13

我只想写下我所做过的和对我有效的方法(因为我尝试过的其他方法都没有起作用)。

我的问题是IE在打印对话框出现之前会关闭窗口。

经过大量的试验、错误和测试,我终于找到了解决方法:

var w = window.open();
w.document.write($('#data').html()); //only part of the page to print, using jquery
w.document.close(); //this seems to be the thing doing the trick
w.focus();
w.print();
w.close();

这似乎在所有浏览器中都有效。


似乎之前代码是可以工作的,但现在不行了。我会在下面发布我的代码。 - Remco

11

这段代码对我完美地起作用了:

<body onload="window.print()" onfocus="window.close()">

打开页面时会自动弹出打印对话框,打印或取消后窗口会关闭。

希望能帮到您,


如果您打开的是 PDF 文件进行打印而不是 HTML 或 JSP,那么这种方法就无法使用了。在哪里放置 onload body? - shareef
谢谢您的帖子,这个方法对我很有用,因为在移动设备上保存为PDF时不会显示错误。 - Samuel Ramzan

11

只需通过onafterprint事件处理程序包装window.close,这对我有效。

printWindow.print();
printWindow.onafterprint = () => printWindow.close();

1
需要Safari v12。 - Paul Brady

10

这是一个跨浏览器解决方案,截至2016/05已在Chrome、Firefox和Opera上进行了测试。

请注意,Microsoft Edge存在一个bug,如果取消打印,将无法关闭窗口。相关链接

var url = 'http://...';
var printWindow = window.open(url, '_blank');
printWindow.onload = function() {
    var isIE = /(MSIE|Trident\/|Edge\/)/i.test(navigator.userAgent);
    if (isIE) {

        printWindow.print();
        setTimeout(function () { printWindow.close(); }, 100);

    } else {

        setTimeout(function () {
            printWindow.print();
            var ival = setInterval(function() {
                printWindow.close();
                clearInterval(ival);
            }, 200);
        }, 500);
    }
}

7

参考 来源引用

<script type="text/javascript">
  window.print();
  window.onafterprint = window.close;   
</script>

7
使用Chrome浏览器时,我尝试了一段时间才让window.onfocus=function() { window.close(); }<body ... onfocus="window.close()">起作用。我的结果是:
  1. 我关闭了打印对话框,没有任何反应。
  2. 我在浏览器中切换了窗口/标签页,仍然没有反应。
  3. 切换回我的第一个窗口/标签页,然后window.onfocus事件触发并关闭了窗口。

我还尝试了<body onload="window.print(); window.close()" >,但在我点击打印对话框中的任何内容之前,窗口就被关闭了。

我不能使用这两个方法。因此,我使用了一点Jquery来监视文档状态,以下代码可以正常工作。

<script type="text/javascript">
    var document_focus = false; // var we use to monitor document focused status.
    // Now our event handlers.
    $(document).focus(function() { document_focus = true; });
    $(document).ready(function() { window.print(); });
    setInterval(function() { if (document_focus === true) { window.close(); }  }, 500);
</script>

请确保您已经引入了jQuery库,然后将以下代码复制/粘贴到您要打印的HTML中。如果用户已经打印、保存为PDF或取消了打印作业,则窗口/选项卡将自动销毁。注意:我只在Chrome浏览器中进行了测试。

编辑

正如Jypsy在评论中指出的那样,文档焦点状态是不必要的。您可以直接使用noamtcohen的答案,我将我的代码更改为那个答案,它可以工作。


这个解决方案会导致如果用户关闭弹出窗口而不是选择取消或打印,则原始窗口挂起。这与Juan的解决方案存在相同的问题,@JFK最初指出了这一点。 - Clayton
以上的JavaScript应该放置在打印的HTML中,无论是在弹出窗口中还是像我一样在新选项卡中打开。因此,这个JavaScript不会对原始窗口产生影响。 - Nado11

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接