.appendChild和window.print();

时间:2018-06-04 23:02:59

标签: javascript

我有以下代码:

const printString = // a long string w/ several base64 encoded images;
const printContainer = document.createElement('div');
printContainer.innerHTML = printString;
document.body.appendChild(printContainer);
window.print();

printString是一个长字符串,包含几个大的base64编码图像。该字符串被设置为innerHTML的{​​{1}},然后整个内容被打印出来。

这没关系,但是在页面的初始加载时,它显然需要浏览器片刻来渲染base64编码的图像,并且在这段时间内,printContainer继续发射并在所有之前触发图像实际上已加载到DOM 中。

也就是说,window.print()可以在window.print()完成呈现新元素之前触发。

如果我向.innerHTML添加一个短暂的延迟,那么一切正常。像这样:

window.print()

然而,这并不是一个很好的解决方案,我真的希望找到一个解决方案,你只需要等到const printString = // a long string w/ several base64 encoded images; const printContainer = document.createElement('div'); printContainer.innerHTML = printString; document.body.appendChild(printContainer); setTimeout(() => { window.print(); }, 100); 实际完成,.innerHTML() < / p>

到目前为止,所有这些都在Chrome中进行了测试。

任何想法都赞赏!

编辑:答案

这是对@ Keith的回答的适度修改。

window.print();

2 个答案:

答案 0 :(得分:2)

下面是一个等待加载所有图像的简单脚本。

它基本上是一个querySelectAll来获取所有图像,然后附加onload事件,当加载的图像数量等于列表中的图像数量时,所有内容都会被加载。

这当然适用于外部URL和数据uri ..

  

更新,发现我的原始图片加载检查存在轻微问题,在Chrome中有时候onload没有被触发,我认为这是因为如果它可以从缓存中提取资源,它可能会在onload事件之前加载甚至是附加的,因此我首先添加了对完整标志的检查。这似乎解决了这个问题..

const imgs = document.querySelectorAll("img");

let waiting = 0;
let count = 0;

function checkDone() {
  if (count === waiting) {
    console.log("all images loaded");
  }
}

for (const img of imgs) {
  if (!img.complete) waiting ++;
  else img.addEventListener('load', () => {
    count ++;
    checkDone();
  });
}
checkDone();
<img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" style="width:100px;height:100px">
<img src="https://via.placeholder.com/350x150.svg">
<img src="https://via.placeholder.com/300x100.svg">
<img src="https://via.placeholder.com/200x400.svg">

答案 1 :(得分:0)

这是使用requestAnimationFrame的好例子。

<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css" rel="stylesheet" />

<div class="container">
  <div class="level main">
    <div class="level-item">
      <figure class="image is-128x128">
        <img src="https://bulma.io/images/placeholders/128x128.png">
      </figure>
    </div>
  </div>
  <div class="notification is-primary">
    <button class="delete"></button> Primar lorem ipsum dolor sit amet, consectetur adipiscing elit lorem ipsum dolor. <strong>Pellentesque risus mi</strong>, tempus quis placerat ut, porta nec nulla. Vestibulum rhoncus ac ex sit amet fringilla. Nullam
    gravida purus diam, et dictum <a>felis venenatis</a> efficitur. Sit amet, consectetur adipiscing elit
  </div>
</div>
<div class="container">
  <div class="level main">
    <div class="level-item">
      <figure class="image is-128x128">
        <img src="https://bulma.io/images/placeholders/128x128.png">
      </figure>
    </div>
  </div>
</div>

const printString = // a long string w/ several base64 encoded images; const printContainer = document.createElement('div'); printContainer.innerHTML = printString; document.body.appendChild(printContainer); requestAnimationFrame(function () { window.print(); }); 等待下一个绘图,然后运行该函数,这样就可以确保requestAnimationFrame在HTML呈现之后才会运行。