新添加的HTML上的Javascript window.print()问题

新添加的HTML上的Javascript window.print()问题,javascript,jquery,html,ajax,printing,Javascript,Jquery,Html,Ajax,Printing,问题是新内容不会打印(再打印几个元素) 当用户单击我的打印链接时,我会在调用window.print()之前向文档添加更多html 在打印之前,我使用ajax为一本书获取更多章节 代码: 打印已初始化: var afterPrint = function () { var timer = setInterval(function () { afterContentPrint(); // Cleanup html (restore to initial state) cle

问题是新内容不会打印(再打印几个元素)

当用户单击我的打印链接时,我会在调用window.print()之前向文档添加更多html

在打印之前,我使用ajax为一本书获取更多章节

代码:

打印已初始化:

var afterPrint = function () {

  var timer = setInterval(function () {

    afterContentPrint(); // Cleanup html (restore to initial state)
    clearInterval(timer);

  }, 900);
}
//window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;
事件打印单击:

$("#print-test").click(function (e) {

   e.preventDefault();

   beforeContentPrint(); // ajax call for additional content, finishing by calling window.print()
});
在函数beforeContentPrint()中:

新内容明显地添加到HTML文档中,因此它应该可以工作。但是只有最初的内容(在ajax调用之前)才会被打印出来

此解决方案适用于IE和Firefox(onbeforeprint和onafterprint)


使用window.matchMedia('print')在Chrome中使用这种逻辑似乎可以很好地工作。

它看起来像是setInterval,clearInterval把你搞砸了。更改为setTimeout并在afterprint函数中删除clearInterval。我做了一把小提琴,可以在FF和IE9中使用


我不知道为什么会发生这种情况,但mozilla文档中有一个解决方案;打印一个隐藏的iframe,然后您可以打开本书的更多章节,而无需显示。 这里是链接

代码如下:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>MDN Example</title>
<script type="text/javascript">
function closePrint () {
  document.body.removeChild(this.__container__);
}

function setPrint () {
  this.contentWindow.__container__ = this;
  this.contentWindow.onbeforeunload = closePrint;
  this.contentWindow.onafterprint = closePrint;
  this.contentWindow.print();
}

function printPage (sURL) {
  var oHiddFrame = document.createElement("iframe");
  oHiddFrame.onload = setPrint;
  oHiddFrame.style.visibility = "hidden";
  oHiddFrame.style.position = "fixed";
  oHiddFrame.style.right = "0";
  oHiddFrame.style.bottom = "0";
  oHiddFrame.src = sURL;
  document.body.appendChild(oHiddFrame);
}
</script>
</head>

<body>
  <p><span onclick="printPage('externalPage.html');" style="cursor:pointer;text-decoration:underline;color:#0000ff;">Print external page!</span></p>
</body>
</html>

MDN示例
函数closePrint(){
document.body.removeChild(这个容器);
}
函数setPrint(){
this.contentWindow.\uuuuu容器\uuuu=this;
this.contentWindow.onbeforeunload=closePrint;
this.contentWindow.onafterprint=closePrint;
这个.contentWindow.print();
}
函数打印页(sURL){
var oHiddFrame=document.createElement(“iframe”);
oHiddFrame.onload=设置打印;
oHiddFrame.style.visibility=“隐藏”;
ohidframe.style.position=“固定”;
oHiddFrame.style.right=“0”;
oHiddFrame.style.bottom=“0”;
oHiddFrame.src=sURL;
文档.body.appendChild(oHiddFrame);
}
打印外部页面


第一次尝试:尝试在beforeContentPrint的ajax请求中放置asyn:false,以便先添加元素,然后调用打印

var jqxhr = $.ajax({

   type: "GET",
   url: bookURL,
   async:false,
   success: function(data) {
     .....
     .....

     $(article).each(function () {
        parent.append(article);

     });
   },
   complete: function() {
     var timer = setInterval(function () {
        window.print();
     }, 900);
  }
 }
2ndatest:看看如何强制执行一个又一个函数。
希望这能有所帮助。

由于添加的元素没有显示出来,所以要找出确切的问题可能有点困难,但是通过追加/插入文档来添加元素并不总是对所有浏览器都有效,在最坏的情况下,您需要通过代码手动添加这些元素(
document.createElement()
appendChild())
等)

在尝试创建一个工作环境时,您可以尝试使用跟踪您的文章元素的更改,这有望帮助您在DOM正确更新时触发打印。这种支持在新浏览器中相当好(在某些浏览器中可能需要使用前缀,例如,
webkit-mutationobserver
),而对于旧浏览器,则可以提供一种回退,这当然只能让您做到这一点

这将监视目标元素的更改并触发回调

基于以下内容的通用示例:

现在观察器正在运行,您可以在成功回调中进行此修改:

var timer;  // keep track of setTimeout so we can cancel it

success: function(data) {
   ...
   ...

$(article).each(function () {

    parent.append(article);

  });

  // after last element is added, add a "dummy" element
  doPrint = true;

  if (useFallback) {
     // fallback to setTimeout or other solution
  }
  else {
     parent.append('<br />');
  }

}
var定时器;//跟踪setTimeout,以便我们可以取消它
成功:功能(数据){
...
...
$(文章)。每个(函数(){
附加(第条);
});
//添加最后一个元素后,添加一个“虚拟”元素
doPrint=true;
如果(使用回退){
//回退到setTimeout或其他解决方案
}
否则{
parent.append(“
”); } }
我制作了一个,它设置了观察者并添加了一些元素。打开控制台查看操作。演示的数据可能太有限,无法模拟您的情况,但可以帮助您了解过程

这里使用的触发打印对话框本身的机制可以讨论,如果是最好的-我只是提供一个例子

但您可以看到,当向
文章添加内容时,会触发观察者。这样您就知道DOM已经更新,应该可以打印了。只有添加的最后一个元素需要触发打印,因此使用
doPrint
标志


如果您仍然没有成功,您将需要考虑手动添加元素的代码方式,或者可能预先定义在需要时注入的一些元素(如所说,不知道这里必须与猜测一起的全部场景)。

我在调用打印之前几秒钟就使用<代码> StimeTimeOut/<代码>,但它不起作用。我还试图通过对ajax使用
success:function(data){}
和对
window.print使用
complete:function(){}
来分离这两个进程,但这也没有解决问题。Hmmm。打印预览或通过Ctrl+P打印是否输出所有页面?OP有完整回调的window.print,成功后肯定会调用该回调。。。显然异步不是问题
var jqxhr = $.ajax({

   type: "GET",
   url: bookURL,
   async:false,
   success: function(data) {
     .....
     .....

     $(article).each(function () {
        parent.append(article);

     });
   },
   complete: function() {
     var timer = setInterval(function () {
        window.print();
     }, 900);
  }
 }
var article = document.querySelector('#articleID'),
    doPrint = false,    // must be available in global/parent scope
    o,
    useFallback = (typeof MutationObserver !== 'undefined');


if (!useFallback) {    
    o = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {

           // you can do additional filtering here
           // using the mutation object (.name, .type, ...)

           if (doPrint) {
               doPrint = false;
               window.print();
           }
       });
    });

    var cfg = { attributes: true, childList: true, characterData: true };

    o.observe(article, cfg);
}
var timer;  // keep track of setTimeout so we can cancel it

success: function(data) {
   ...
   ...

$(article).each(function () {

    parent.append(article);

  });

  // after last element is added, add a "dummy" element
  doPrint = true;

  if (useFallback) {
     // fallback to setTimeout or other solution
  }
  else {
     parent.append('<br />');
  }

}