dom 为什么必须刷新才会响应 $nextTick 中调用 window.print() 后影响 dom 的操作 ?

作者站长头像
站长
· 阅读数 13

代码示例如下:

...
<div :id="pageStyle" ref="page" >
...
    // 打印函数
    fun() {
    //将要打印的区域修改为打印样式
    this.pageStyle='pageprint'
      this.$nextTick(()=>{
        //将要打印的区域单独保存到变量中
        let printHtml = this.$refs.page.innerHTML; 
        //将完整的页面保存到变量中
        let oldHtml = window.document.body.innerHTML;
        //修改页面,只保留要打印的部分
        document.body.innerHTML = printHtml;
        //打印页面
        window.print();
        //打印完成后,将页面恢复为完整页面
        document.body.innerHTML = oldHtml;
        //恢复打印区域的样式
        this.pageStyle='page'
        // 就是这一句,为什么不加的话this.pageStyle='page' 就不会生效?
        this.$router.go(0)
      })
    },
...
#page{...}
#pageprint{...}

我知道 DOM 的刷新是在这一轮计算完成之后才进行,只有 this.$nextTick 中的运算是在 DOM 刷新后才进行的,那我在 this.$nextTick 中进行了会引起页面刷新的运算不就应该在这些运算结束后再一次引起 DOM 刷新?可是这里为什么还要加一个刷新页面才可以生效?

回复
1个回答
avatar
test
2024-07-04

试试这个方法:

fun() {
  this.pageStyle = "pageprint";
  this.$nextTick(() => {
    let iframe = document.createElement("iframe");
    iframe.style.display = "none";
    document.body.appendChild(iframe);

    const stylesheets = Array.from(document.querySelectorAll("link[rel='stylesheet'], style"));
    stylesheets.forEach((stylesheet) => {
      const clonedStylesheet = stylesheet.cloneNode(true);
      iframe.contentWindow.document.head.appendChild(clonedStylesheet);
    });

    iframe.contentWindow.document.body.innerHTML = this.$refs.page.innerHTML;

    iframe.contentWindow.print();

    document.body.removeChild(iframe);

    this.pageStyle = "page";
  });
},
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容