今天在IE11上開發時,發現Echart在IE11上無法渲染出來,控制檯報錯 SCRIPT65535: Invalid calling object
錯誤指向的是Echart依賴的Zrender模塊的requestAnimationFrame模塊,指示requestAnimationFrame方法調用失敗
查閱MSDN關於IE兼容差異的文檔,發現有一篇叫做 函數指針方法調用 的文章
文章大意如下:
早期版本的 Windows Internet Explorer 支持將方法的指針進行緩存並隨後使用緩存的指針來調用方法。自 Windows Internet Explorer 9 開始,取消了這項支持以改善與其他瀏覽器的互操作性。
var d = document.writeln;
d("<script language=VBScript>"); //error Invalid calling object
從 Internet Explorer 9 開始,需要有一個對象才能調用方法。默認情況下,在全局作用域中提供 window 對象(如前面示例中所示)。不過,window 對象沒有 writeln 方法,因此報告 JavaScript 錯誤消息:“調用對象無效”。
解決這個報錯的方案是顯示提供適當的調用對象,或使用 JavaScript 的 bind API 將隱式調用對象與該方法關聯。
d.call(document, '<script language="VBScript">');
or
var d = document.writeln.bind(document);
d("<script language=VBScript>"); // Now this is OK.
根據這個原理,我們稍微修改下requestAnimationFrame模塊
//requestAnimationFrame.js 模塊
module.exports = (typeof window !== 'undefined' &&
(window.requestAnimationFrame
|| window.msRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame))
|| function (func) {
setTimeout(func, 16);
};
修改爲
//requestAnimationFrame.js 模塊
module.exports = (typeof window !== 'undefined' &&
(window.requestAnimationFrame
|| window.msRequestAnimationFrame.bind(window)
|| window.mozRequestAnimationFrame
|| window.webkitRequestAnimationFrame))
|| function (func) {
setTimeout(func, 16);
};
即可解決。
不過,解決這個問題還有另一個方法。
在webpack的配置中,我們在開發環境使用
devtool: 'eval-source-map'
來定位錯誤,去掉eval方式亦可解決此問題,不過原因不詳,還有待探究。
轉載請註明出處。