We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
由于众所周知的原因,Web 应用还是需要兼容 Windows 下最「著名」的浏览器 Internet Explorer 的,可能现在不需要再兼容到 IE6 这么低的版本,但 IE9/10/11 的兼容可能也够麻烦了。
由于我们使用的 Angular + NG-ZORRO-ANTD,两者的官网都说能支持 IE9+,因此我们愉快地开始了 IE 兼容的踩坑之旅。
查阅的无数资料第一步准是让你把 angular-cli 生成项目中的 polyfills.ts 中的一切都打开,本着「加载慢不慢先不管,能不能用最重要」的原则,我们当然把全部都打开了。
polyfills.ts
$ npm install --save classlist.js $ npm install --save web-animations-js $ npm install --save intl
把注释里的全部安装完毕,以为兼容 IE 就是这么 Easy, 打开网页依然是一堆的报错...
我们后端返回的日期时间类型是一个形如 YYYY-MM-DD HH:mm:ss 的字符串,当使用自带的 date 管道进行格式化时:
YYYY-MM-DD HH:mm:ss
date
{{startDate | date: 'YYYY年MM月DD日'}}
报错了,IE11 无法将不标准的日期字符串转换为 Date 对象,因此需要自定义一个日期时间格式化管道。
Date
Solved
在 IE11 下会报这个错,错误定位的代码是这样:
var testString = delegate.toString(); // <===== HERE! if ((testString === FUNCTION_WRAPPER || testString == BROWSER_TOOLS)) { nativeDelegate.apply(target, args); return false; }
去搜了一下,马上就找到解决方法了,出错原因可以看里面的解释。
Angular 4 app using IE 11, “Can't execute code from a freed script”
Angular 4 put a global constant available to zone.js
一模一样的情况,在 index.html 加上一行 script 把那个全局变量加上去。
index.html
script
<body> <app-root></app-root> <script> window['__Zone_disable_IE_check'] = true; </script> </body>
在项目中使用了 Array.prototype.includes 这个 ES7 新特性,需要额外的 polyfills,否则 IE 不支持。到 MDN 找一下就好。
Array.prototype.includes
MDN - Array.prototype.includes()
我们新建了一个 src/polyfills.js 并在 polyfills.ts 的最后 import 进去,把自己实现的 polyfill 放到 js 文件里。
src/polyfills.js
如果要兼容到 IE9,你可以忽略这部分内容了,请禁止你(和团队)使用 Flexbox 吧 :Smile:
在业务中,非常频繁的使用了 Flexbox 布局,CanIUse 上表示 Flexbox 对 IE11 也只是部分支持,IE10 直接标红了。但其实 IE10 能够通过 prefix 来实现。
div { display: -ms-flexbox; }
那当然不可能手动每个 div 加啊,我们需要 PostCSS 的 Autoprefixer,经过一番查找,发现 angular-cli 已经集成了 autoprefixer(╰(°▽°)╯),配置一下浏览器列表就能起效了。
Change target browsers for Autoprefixer
这个问题是一个量子态的问题,偶尔会出现,但关掉 IE 再重启又没问题了,真的是来搞笑的。
暂时认为是 livereload 导致的代码片段出错,不处理。
Observe
我们实现的图片上传组件,使用了 FileReader 来获得图片的 base64 编码,并通过编码上传的服务器。但在 IE9 下,并不支持 FileReader.
FileReader
其实我们只需要能够将图片转成 base64 编码就可以了,查了一下可以用 canvas 来转诶,而且 canvas IE9 也支持,可以尝试。
Under development
在一些自定义的组件中,对一些元素使用了 hidden 属性来进行隐藏,在 IE10 下会无法隐藏。
hidden
<span class="close" [hidden]="!allowRemove || !showControlBtn[i]"> </span>
很可惜,hidden 在 IE10 上并不支持。
改成利用 display: none 来隐藏,问题解决。
display: none
<span class="close" [class.close-not-exist]="!allowRemove || !showControlBtn[i]"> </span>
如果使用了 Angular 的动画 @angular/animation, 在 IE9 下会由于不支持 requestAnimationFrame 而报错。自行加上对应的 Polyfill 即可。
@angular/animation
requestAnimationFrame
需要注意的是,这个 requestAnimationFrame 的 polyfill 需要在 Angular 自带的 polyfills.ts 之前引入,因为下面的代码会用到这个函数,把 import 语句放在 polyfills.ts 的开头即可。
这个跟 Angular 关系不大,我们实现的不少图片上传或文件上传组件,做法都是隐藏一个 input 框,当有某些 click 事件时调用 input.click() 调出文件选择器,选择后通过 change 事件处理。
input.click()
change
在 change 的处理函数的最后,会有这么一句
this.fileEle.nativeElement.value = '';
在每次处理完用户选择的文件后,把该 input 框的值清空。这么做的原因是 change 事件只有在文件变化时才被触发,当需要处理两次上传同一个文件的情况时
符合组件预期的行为应该是调用两次 change 回调。这里需要说明的是,change 本身的语义是没有问题的,只有文件变化才调用,但组件层面上的语义应该是每次用户选择了文件都执行一个回调,因此单纯的 change 事件不能满足需求。
因此每次把 value = '' 即可解决这个问题。
value = ''
但在 IE11 的实现认为,设置 value 相当于改变文件,也需要调用 change 回调(Chrome / Firefox 甚至 IE10 也不会调用),因此 change 回调执行了两次,其中第二次的 e.target.files 为空数组,需要特别的处理。
value
e.target.files
这里有个知乎上的讨论,对 input file 的特性还需要进一步实践,先记录下来
在 IE9 下,启动应用并进入时控制台会报这个错,Int32Array undefined 之类的。找到了这个,加上新的 polyfill 即可。
Int32Array undefined
import 'core-js/es6/typed';
The text was updated successfully, but these errors were encountered:
No branches or pull requests
由于众所周知的原因,Web 应用还是需要兼容 Windows 下最「著名」的浏览器 Internet Explorer 的,可能现在不需要再兼容到 IE6 这么低的版本,但 IE9/10/11 的兼容可能也够麻烦了。
由于我们使用的 Angular + NG-ZORRO-ANTD,两者的官网都说能支持 IE9+,因此我们愉快地开始了 IE 兼容的踩坑之旅。
开启官方提供的 Polyfills
查阅的无数资料第一步准是让你把 angular-cli 生成项目中的
polyfills.ts
中的一切都打开,本着「加载慢不慢先不管,能不能用最重要」的原则,我们当然把全部都打开了。把注释里的全部安装完毕,以为兼容 IE 就是这么 Easy, 打开网页依然是一堆的报错...
逐个击破
date 管道解析报错
我们后端返回的日期时间类型是一个形如
YYYY-MM-DD HH:mm:ss
的字符串,当使用自带的date
管道进行格式化时:报错了,IE11 无法将不标准的日期字符串转换为
Date
对象,因此需要自定义一个日期时间格式化管道。Solved
IE11 报错「不能执行已释放 Script 的代码」
在 IE11 下会报这个错,错误定位的代码是这样:
去搜了一下,马上就找到解决方法了,出错原因可以看里面的解释。
Angular 4 app using IE 11, “Can't execute code from a freed script”
Angular 4 put a global constant available to zone.js
一模一样的情况,在
index.html
加上一行script
把那个全局变量加上去。Solved
Array.prototype.includes polyfills
在项目中使用了
Array.prototype.includes
这个 ES7 新特性,需要额外的 polyfills,否则 IE 不支持。到 MDN 找一下就好。MDN - Array.prototype.includes()
我们新建了一个
src/polyfills.js
并在polyfills.ts
的最后 import 进去,把自己实现的 polyfill 放到 js 文件里。Solved
IE10 Flexbox 支持
在业务中,非常频繁的使用了 Flexbox 布局,CanIUse 上表示 Flexbox 对 IE11 也只是部分支持,IE10 直接标红了。但其实 IE10 能够通过 prefix 来实现。
那当然不可能手动每个 div 加啊,我们需要 PostCSS 的 Autoprefixer,经过一番查找,发现 angular-cli 已经集成了 autoprefixer(╰(°▽°)╯),配置一下浏览器列表就能起效了。
Change target browsers for Autoprefixer
Solved
IE11 无法获取未定义或 null 引用的属性 "call"
这个问题是一个量子态的问题,偶尔会出现,但关掉 IE 再重启又没问题了,真的是来搞笑的。
暂时认为是 livereload 导致的代码片段出错,不处理。
Observe
IE9 不支持 FileReader
我们实现的图片上传组件,使用了
FileReader
来获得图片的 base64 编码,并通过编码上传的服务器。但在 IE9 下,并不支持FileReader
.其实我们只需要能够将图片转成 base64 编码就可以了,查了一下可以用 canvas 来转诶,而且 canvas IE9 也支持,可以尝试。
Under development
IE10 使用了 [hidden] 隐藏元素
在一些自定义的组件中,对一些元素使用了
hidden
属性来进行隐藏,在 IE10 下会无法隐藏。很可惜,
hidden
在 IE10 上并不支持。改成利用
display: none
来隐藏,问题解决。Solved
IE9 requestAnimationFrame undefined
如果使用了 Angular 的动画
@angular/animation
, 在 IE9 下会由于不支持requestAnimationFrame
而报错。自行加上对应的 Polyfill 即可。需要注意的是,这个
requestAnimationFrame
的 polyfill 需要在 Angular 自带的polyfills.ts
之前引入,因为下面的代码会用到这个函数,把 import 语句放在polyfills.ts
的开头即可。Solved
IE11 下改变 file input value 会重新触发 change 事件
这个跟 Angular 关系不大,我们实现的不少图片上传或文件上传组件,做法都是隐藏一个 input 框,当有某些 click 事件时调用
input.click()
调出文件选择器,选择后通过change
事件处理。在
change
的处理函数的最后,会有这么一句在每次处理完用户选择的文件后,把该 input 框的值清空。这么做的原因是
change
事件只有在文件变化时才被触发,当需要处理两次上传同一个文件的情况时符合组件预期的行为应该是调用两次
change
回调。这里需要说明的是,change
本身的语义是没有问题的,只有文件变化才调用,但组件层面上的语义应该是每次用户选择了文件都执行一个回调,因此单纯的change
事件不能满足需求。因此每次把
value = ''
即可解决这个问题。但在 IE11 的实现认为,设置
value
相当于改变文件,也需要调用change
回调(Chrome / Firefox 甚至 IE10 也不会调用),因此change
回调执行了两次,其中第二次的e.target.files
为空数组,需要特别的处理。Solved
IE9 下 Int32Array undefined
在 IE9 下,启动应用并进入时控制台会报这个错,
Int32Array undefined
之类的。找到了这个,加上新的 polyfill 即可。The text was updated successfully, but these errors were encountered: