IE11下DC.js仪表盘截图功能实现时promise.js报错求助
我之前在做类似的SVG转Canvas截图功能时,也踩过IE11的不少坑,结合你的场景,给你几个针对性的排查和解决方向:
1. 先搞定Promise兼容性(最可能的元凶)
IE11原生完全不支持ES6 Promise,而html2canvas或者你用到的SVG转Canvas工具大概率依赖了Promise,这就是你看到promise.js报错的核心原因。
解决办法很直接:引入Promise polyfill,比如es6-promise,一定要确保在你的截图逻辑、html2canvas脚本之前加载这个polyfill。示例代码如下:
// 先加载polyfill (function() { if (!window.Promise) { // 这里可以直接引入polyfill的代码,或者通过脚本标签加载 // 比如es6-promise的polyfill核心逻辑 window.Promise = ES6Promise.Promise; } })();
(如果是用npm管理依赖,可以直接安装es6-promise并在入口文件导入)
2. 确保SVG样式内联彻底,适配IE11的渲染逻辑
你提到克隆对象来加内联样式,但IE11对SVG的样式处理很严格——外部CSS类在克隆后的SVG元素上可能不会被正确解析,哪怕你给父DIV加了样式也没用。
建议写一个递归函数,把SVG及其所有子元素的计算样式都手动内联到元素的style属性里:
function applyInlineStyles(el) { const styleObj = window.getComputedStyle(el); // 遍历所有计算出的样式属性,逐个设置到元素style上 Array.from(styleObj).forEach(prop => { el.style[prop] = styleObj[prop]; }); // 递归处理子元素 Array.from(el.children).forEach(child => applyInlineStyles(child)); } // 克隆容器后,对所有元素应用内联样式 const chartContainer = document.getElementById('your-chart-div'); const clonedContainer = chartContainer.cloneNode(true); applyInlineStyles(clonedContainer);
3. 选用兼容IE11的html2canvas版本
新版本的html2canvas已经放弃了IE11支持,如果你用的是较新的版本,大概率会出现兼容问题。建议回退到html2canvas v1.0.0-rc.4,这个版本是最后一批支持IE11的稳定版本。
同时调用html2canvas时,加上这些适配IE11的配置:
html2canvas(clonedContainer, { useCORS: true, // 处理跨域图片(如果有的话) logging: true, // 开启日志,方便排查IE11下的具体报错点 scale: 1 // 避免IE11下缩放导致的模糊或渲染异常 }).then(canvas => { // 后续截图处理逻辑 });
4. 检查SVG克隆的命名空间问题
IE11在克隆SVG元素时,容易丢失SVG的命名空间(http://www.w3.org/2000/svg),导致SVG无法正常渲染。如果你的克隆逻辑是用cloneNode(true),可以手动检查克隆后的SVG元素的命名空间是否正确,或者直接手动创建SVG克隆:
function cloneSVG(svg) { const cloned = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); cloned.setAttribute('viewBox', svg.getAttribute('viewBox')); cloned.setAttribute('width', svg.getAttribute('width')); cloned.setAttribute('height', svg.getAttribute('height')); // 复制所有子元素 while (svg.firstChild) { cloned.appendChild(svg.firstChild.cloneNode(true)); } return cloned; }
按照这个顺序排查,先解决Promise的问题,再处理样式和克隆的兼容问题,应该能解决IE11下的报错。
内容的提问来源于stack exchange,提问作者timJIN520

