Angular 12调用dom-to-image-more的toPng时报c.getComputedStyle is not a function错误
错误根因
c.getComputedStyle is not a function 报错本质是 dom-to-image-more 库内部调用 window.getComputedStyle 方法时上下文丢失,或者处理到了非标准DOM元素导致方法入参异常。以下是按优先级排列的排查解决步骤:
- 检查调用时机与节点合法性
确保调用导出方法时,组件已完成ngAfterViewInit生命周期,节点完全挂载。调用前新增节点合法性判断:
downloadMap = (): void => { // 新增节点校验 if (!this.leafletMap?.nativeElement || !(this.leafletMap.nativeElement instanceof HTMLElement)) { return; } domtoimage.toPng(this.leafletMap.nativeElement).then((img: any) => { console.log(img); }); };
- 手动绑定getComputedStyle上下文
这是该场景下最高发的问题,dom-to-image-more内部运行时可能丢失window上下文,手动绑定方法指向即可解决:
downloadMap = (): void => { const originalGetComputedStyle = window.getComputedStyle; // 手动绑定window上下文 window.getComputedStyle = (...args) => originalGetComputedStyle.apply(window, args); domtoimage.toPng(this.leafletMap.nativeElement) .then((img: any) => { console.log(img); window.getComputedStyle = originalGetComputedStyle; }) .catch(err => { console.error(err); // 报错也要恢复原生方法避免影响其他逻辑 window.getComputedStyle = originalGetComputedStyle; }); };
- 新增节点过滤规则,跳过Leaflet非兼容节点
Leaflet内部包含大量动态生成的SVG、canvas图层与自定义控件,部分特殊节点会导致dom-to-image-more解析异常,通过filter配置过滤无效节点:
downloadMap = (): void => { domtoimage.toPng(this.leafletMap.nativeElement, { filter: (node: Node) => { // 仅处理标准元素节点,跳过文本、注释等非元素节点 if (node.nodeType !== Node.ELEMENT_NODE) return false; // 可按需过滤不需要导出的Leaflet控件 // if ((node as HTMLElement).classList.contains('leaflet-control')) return false; return true; } }).then((img: any) => { console.log(img); }); };
- 检查库版本兼容性
高版本dom-to-image-more存在Angular环境兼容问题,可降级到2.13.0稳定版测试:
npm install dom-to-image-more@2.13.0
- 排除Angular Zone与SSR干扰
如果项目开启了变更检测优化或者服务端渲染,做对应兼容处理:
import { NgZone } from '@angular/core'; import { isPlatformBrowser, PLATFORM_ID } from '@angular/common'; import { Inject } from '@angular/core'; export class MyComponent { @ViewChild('leafletMap') leafletMap: ElementRef; constructor( private ngZone: NgZone, @Inject(PLATFORM_ID) private platformId: Object ) {} downloadMap = (): void => { // SSR环境下不执行导出逻辑 if (!isPlatformBrowser(this.platformId)) return; // 放到Angular Zone外运行避免变更检测拦截DOM方法 this.ngZone.runOutsideAngular(() => { domtoimage.toPng(this.leafletMap.nativeElement).then((img: any) => { console.log(img); }); }); }; }
内容的提问来源于stack exchange,提问作者tbarbot
相关产品推荐
相关产品推荐

