React+reflu应用 IE8/9/10/11兼容实践

一、挑战

原本的平台业务只在手机移动端上跑,所以日常开发的习惯都是不考虑(也不需要考虑)兼容性的问题。平时会使用很多在低级别浏览器(IE8+)无法运行的API和框架(React、reflux)。在某次合作方接入竞猜平台的需求中,怎么让应用在我们PC端上跑起来,便成了挑战,也是这篇文章的起点~

二、思路/解决

1、分析数据确定方向

首先确定主要攻坚的浏览器版本类型,于是跑到度娘那查了一下全国的浏览器占比数据:

另外要了公司某游戏部门官网的数据:

分析数据得出,chrome、IE8、IE9、IE10、IE11是我们的主要目标。

本次文章主要讲IE8、IE9、IE10、IE11的兼容~ 其他版本太低的IE就不管了:D

2、观察确定记录现状

第二步,在还没做任何兼容措施的情况下,应用出现了以下问题:

  1. postMessage数据传递失效 —— IE9及以下

  2. console对象undefined —— (小部分IE9)及以下

  3. Array对象的isArray方法undefined —— IE8及以下

  4. Object.defineProperty 方法undefined —— IE8及以下

  5. addEventListener兼容性问题 —— (小部分IE9)及以下

  6. 操作dom无权限 —— IE9及以下

  7. ....

  8. ....

咋看一下,问题好像很多。但其实都是一些可以快速兼容的问题。

样式问题这里就不写啦, 重构同学自动背锅。:D

3、对比及确定解决方案

兼容方案方向是用shim/polyfill库来对低级浏览器各个缺失的API、对象做补全。

http://www.cnblogs.com/ziyunfei/archive/2012/09/17/2688829.html

我这里列举了一些github上比较常见、靠谱的方案:

感谢github

1)ieBetter

  1. 优点:小而精的polyfill库

  2. 缺点:console、Object.defineProperty都没做处理。

  3. 地址:https://github.com/zhangxinxu/ieBetter.js

2)es5-shim/es5-sham

  1. 优点:多而全、可靠的shim库

  2. 缺点:console/addEventListener没做容错兼容,Object.defineProperty在某些特殊版本有可能会有问题,但是基本可用。

  3. 这作者还有做es6的shim,有兴趣的同学可以了解一下

  4. 地址:https://github.com/es-shims/es5-shim

3)console-polyfill

  1. 简单的console兼容库~

  2. 地址:https://github.com/paulmillr/console-polyfill

4)json3

  1. 简单的json兼容库~

  2. 地址:http://bestiejs.github.io/json3/

5)html5Shiv

  1. html5shiv主要解决HTML5提出的新的元素(section,header,footer)不被IE6-9识别,这些新元素不能作为父节点包裹子元素,并且不能应用CSS样式。html5shiv就是为了解决这个问题存在的。

  2. 地址:https://github.com/aFarkas/html5shiv

6)addEventListener-polyfill.js

  1. 简单的addEventListener兼容库~

  2. 地址:https://gist.github.com/eirikbacker/2864711

7)ie8

  1. 一个IE8的shim库

  2. 地址:https://github.com/WebReflection/ie8

8)dom4

  1. 让IE8获得dom level4的能力

  2. 地址:https://github.com/WebReflection/dom4

===============================================================

经过各种测试/搭配/组合,得出下面这套比较可靠的方案:有问题欢迎交流...

//es5-shim + es5-sham + console-polyfill + json3 + html5Shiv + addEventListener-polyfill.js//最后一个addEventListener-polyfill.js是直接github Raw下来的,建议自己保存

安利https://cdnjs.com/ 是个好东西,搜github一些dist文件很方便,而且不用翻墙

三、陷阱/深坑

在引入shim库之后,还踩了挺多莫名其妙的陷阱,下面我一个一个列举出来:

1、IE兼容性文档视图

登过国内网银页面的同学应该都知道,网银的页面一般不兼容高版本的IE,所以IE下有兼容性视图的选项。对于我们来说,有可能会有IE11的用户跑在IE7的模式下面。

- 修复手段

这个陷阱可以通过设置meta来解决:

有兴趣的同学可以通过阅读下方文章,了解这代码的含义:

https://msdn.microsoft.com/zh-cn/library/cc288325

http://www.cnblogs.com/nidilzhang/archive/2010/01/09/1642887.html

2、特定版本React的兼容性问题

处理完陷阱1之后,开始遇到这么一个问题:

直接看error信息,应该是对一个undefined对象引用了length报的错。

为了查明原因,跟进React源码(0.13.0版本的压缩版源码)看 ,发现是IE8下的firstChild.data undefined了。代码片段如下:

e.innerHTML = "" + t;var n = e.firstChild;1 === n.data.length ? e.removeChild(n) : n.deleteData(0, 1);

在IE8下,e.firstChild是一个null对象。所以会导致那样的报错,关于这个bug的文档说明可以参考:

http://www.cnblogs.com/joyeecheung/p/4168521.html

http://www.cnblogs.com/joyeecheung/p/4168521.html

- 修复手段

修复手法是在设置innerHtml的时候,前置一个bom头\uFEFF。

e.innerHTML = "\uFEFF" + t;var n = e.firstChild;1 === n.data.length ? e.removeChild(n) : n.deleteData(0, 1);

但其实,React的0.13.0版本的非压缩版是有做相关处理的(所以一开始我用非压缩版是可以跑起来的)不知道为何min版本却被压没了。超级大坑...

后来在0.13.2版本min下,已经修复了,遂升级了一下我们的React,这个陷阱就跨过去了~

这是折腾了我最久的坑...超级坑...

3、压缩算法导致的问题

搞好了陷阱1、陷阱2之后,遇到了reflux罢工的问题。

定位后发现平台的压缩算法(普通压缩和UglifyJS)。会让模块在IE8有兼容性问题。

大概看了源码,发现可能是混淆压缩之后的对象被覆盖实例化了。这里只是猜测,有兴趣的同学可以自己去研究一下。

单纯用普通压缩,reflux就跑起来了~

4、innerHTML问题

重构同学做了一下关于IE8的css hack

body{background:# 000 \9;}

重构同学请注意~

- 修复手段

一个\不行就用两个\。

body{background:# 000 \\9;}

四、总结

至此,应用已经能在IE8/9/10/11跑起来了。其中辛酸苦逼无法形容。

定位疑难杂症的时候,应当保持思路清晰,多做排除/置换/简化,来剥离出病因。

卡住了,要多深呼吸冷静下来。再或者去25楼运动一下,说不定有奇效。

如果有什么问题欢迎RTX联系~

后续会补全兼容后的业务数据提升~

五、附件

附件有一个简单的demo,欢迎大家下载使用。

关键字:JavaScript, react.js, reflux, ie8兼容性

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部