You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular项目中Chrome首次调用window.print()异常的解决方法问询

Angular打印URL重置问题解决方法

问题原因

Chrome/Edge浏览器中,首次调用window.print()时,打印预览窗口的启动属于异步过程,此时浏览器尚未完全锁定页面状态,紧接着执行的router.navigate会优先修改URL,导致打印依赖的参数丢失。第二次打印时,浏览器已缓存打印上下文,不会被导航操作干扰;Naver Whale 126的Chromium内核对打印事件时序做了优化,规避了该冲突。

解决方案

方案1:监听打印完成事件再执行路由导航

通过window.onafterprint事件,确保打印预览窗口关闭后才修改路由,避免URL在打印过程中被重置。

修改print.service.ts代码:

onDataReady() {
    setTimeout(() => {
        this.isPrinting = true;
        window.print();
        
        // 绑定打印完成/关闭后的回调
        const afterPrintHandler = () => {
            this.router.navigate([{outlets: {print: null}}]).then(console.info);
            window.removeEventListener('afterprint', afterPrintHandler); // 移除监听防止重复触发
        };
        window.addEventListener('afterprint', afterPrintHandler);
    });
}

方案2:确保DOM完全渲染后再触发打印

利用Angular的AfterViewChecked生命周期钩子,等待数据加载完成且DOM渲染完毕后再调用打印,避免因DOM未就绪导致的打印异常。

修改label.component.ts:

import { OnInit, AfterViewChecked, ChangeDetectorRef } from '@angular/core';

export class LabelComponent implements OnInit, AfterViewChecked {
    private isDataReady = false;

    constructor(private cdr: ChangeDetectorRef) {}

    async ngOnInit() {
        this.QRwidth = 50;
        const dlvyDto = new MakrDlvyOrdGroupNoDto();
        dlvyDto.ordNoList = this.invoiceIds;
        this.orderDetails = await this.rest.postDlvyPrint(dlvyDto).toPromise();
        this.isDataReady = true;
        this.cdr.detectChanges(); // 强制触发变更检测更新DOM
    }

    ngAfterViewChecked() {
        if (this.isDataReady) {
            this.printService.onDataReady();
            this.isDataReady = false; // 仅执行一次打印触发
        }
    }
}

同时调整print.service.ts,仍保留afterprint事件处理路由:

onDataReady() {
    window.print();
    this.isPrinting = true;
    
    const afterPrintHandler = () => {
        this.router.navigate([{outlets: {print: null}}]).then(console.info);
        window.removeEventListener('afterprint', afterPrintHandler);
    };
    window.addEventListener('afterprint', afterPrintHandler);
}

方案3:临时禁用首次打印的路由导航(应急方案)

若无需立即关闭打印路由出口,可先注释掉导航逻辑,待确认打印正常后再结合上述方案优化:

onDataReady() {
    setTimeout(() => {
        window.print();
        this.isPrinting = true;
        // 临时注释导航,测试打印正常后再恢复
        // this.router.navigate([{outlets: {print: null}}]).then(console.info);
    });
}

内容的提问来源于stack exchange,提问作者DevRecord

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 19:50:55