兼容篇是我最想写的一部分,在这以前也总结过不少关于移动开发的兼容问题与解决方案。对于移动Web开发来讲,兼容是开发重心,一般要花费30%甚至更多的时间去处理一些兼容问题,甚至时间花掉了,问题依然没法解决。css
相比PC Web开发,移动开发的兼容性须要考虑的问题更复杂,我本身花了一个图:html
在上图中,我列了两个维度:标准支持和个性化,我以为这两个维度能很好的体现PC与移动在兼容方面的差别。android
PC Web开发中,更多时候是在处理对标准支持程度的兼容问题,问题类型相对比较单一。在进入到IE9+时代,对HTML5特性与其余标准支持已经愈来愈好,前端工程师已经得到了很大的解脱,可能描述得有必定的片面性,但差很少就是这样。git
反观移动端,还处于初级阶段,相比PC浏览器来讲,移动浏览器对标准的支持起步较高,从Android2.1+就已经支持了很大一部分的HTML5基础功能,对ECMAScript 5的支持更是好,但这并不表明移动端的兼容性就很是的好处理。如上面那张图,移动浏览器的个性十足,各个厂商都有本身特有的东西,这就给移动开发的兼容性带来了十分大的挑战。程序员
移动Web开发的兼容问题主要能够从如下几个层面来理解:github
这三种差别,依次是设备 < 操做系统 < 浏览器
,越接近应用层,须要处理的兼容问题越多。web
可能有些人不解,为何设备差别会致使兼容问题呢?其实在前面的交互篇就已经有提到移动设备的物理属性的差别,这就直接致使了在移动Web开发的兼容问题。好比有些比较老旧设备的触摸屏是不支持多点触控的,只能捕获单点,这就使得一些须要多点触摸的应用场景出现兼容问题,好比图片的放大、缩小。相似这种硬件缺胳膊少腿的问题是硬伤,没法解决,通常遇到了也只能忽略,但能够考虑给用户一个提示。固然时代在变化,并且变化得很快,这样的手机毕竟只是少数,就像抛弃IE6同样抛弃它吧。浏览器
另一个问题就是devicePixelRatio(设备像素比)的问题,在前面视觉篇分享过两篇文章,能够拿到这再分享一次:微信
devicePixelRatio主要影响的是图片显示的问题,devicePixelRatio的发展有两个趋势:
devicePixelRatio==1.5
这样的值,可能致使图片显示锯齿;devicePixelRatio==3
甚至大于3,因此图片显示可能会比较虚;在没有特殊要求的状况下,通常移动端是不对图片作特殊处理的,统一都是使用2x
大小的图片。处理时通常分为两种状况:
直接引用图片<img src="xxx.png">
,直接使用2x
大小的图片,将图片高宽设置为物理像素的1/2既可。
另外一种情形就是最多见的背景图,将background-size
设置为物理像素的1/2。好比图片物理像素为200*200,代码以下:
<style> #b1 { width: 100px; height: 100px; background: url("xxx.png") no-repeat; -webkit-background-size: 100px 100px; background-size: 100px 100px; } </style> <div id="b1"></div>
如遇到一些须要背景图自适配宽度的应用场景,可使用background-size: cover;
。
操做系统差别与浏览器差别是会产生重叠知识点,操做系统差别更偏向于描述因为iOS、Android或其余系统差别致使的兼容问题,而浏览器差别偏向描述因为不一样浏览器厂商致使的兼容问题。
相比硬件设备来讲,操做系统也给移动开发带来了很多麻烦,在前面视觉篇的最后已经提到一个字体兼容的问题,参见:@元彦 给出了解决方案 《字体设置最佳实践》。
另一个比较经典的问题,在Android下orientationchange
事件回调,须要延迟一点时间触发回调函数,才能获取到正确的window.innerWidth
和window.innerHeight
的值,在iOS是不须要作这个延迟的。分别使用iOS与Andorid设备访问 DEMO,横竖屏查看对比结果。
我通常会将Android设备的回调延迟300ms处理,代码以下:
var isAndroid = /android/.test(window.navigator.userAgent.toLowerCase()); function createOrientationChangeProxy(fn) { return function() { clearTimeout(fn.orientationChangeTimer); var args = Array.prototype.slice.call(arguments, 0); fn.orientationChangeTimer = setTimeout(function() { var ori = window.orientation; if (ori != fn.lastOrientation) { fn.apply(null, args); } fn.lastOrientation = ori; }, isAndroid ? 300 : 0); }; } window.addEventListener('orientationchange', createOrientationChangeProxy(function() { if (window.orientation == 0 || window.orientation == 180) { resizeIcon(); } }), false);
但其实,即便延迟300ms也不能解决全部Android设备的问题,好比我在小米2原生浏览器上须要延迟800ms才能获取到正确高宽。我想这与小米浏览器的内部实现有关,一些浏览器在进入全屏状态收起地址栏时,会执行一个收起地址栏动画,这个动画大概要消耗500ms左右的时间,这个动画并非全部浏览器都是这么实现的,因此,我想多是由于这个缘由致使有些浏览器须要更长时间才能获取到正确的高宽,也多是我猜错了。
另外,我还在三星手机上遇到过一些更奇葩的问题,使用JavaScript处理animation动画时,设置动画属性。好比:transform
或animation
时,必须使用-webkit
前缀的属性,若是没有这个前缀,在三星手机原生浏览器下,动画会失效,而在其余浏览器下使用前缀的属性是OK的。
操做系统差别与浏览器差别,没有一个完整的边界,产生的问题也模拟两可。若是在全部Android设备上都出相同的问题,这样的问题均可以认为是操做系统差别,通常这类问题都是因为Webkit内核或系统底层的一些缘由致使。
对于移动Web开发来讲,咱们处理的70%兼容问题都会是浏览器差别致使,在这里我不会总结浏览器差别的兼容问题,由于实在太多,阅读过 @jtyjty99999 mobileTech项目 就能体会到,那个篇幅,那个长度,简直无力吐槽。能够这么说,只要浏览器版本在更新,就会不断有新的兼容问题产生,一切浏览器个性化功能和对底层引擎的优化都是兼容问题的罪恶之源。
可是,要确定一点,移动开发兼容通常只须要作两种浏览器的兼容:Webkit内核与IE的Trident内核。若是不考虑WP用户的话,更是连IE兼容均可以省了,因此写代码时,都优先考虑-webkit
前缀的兼容,这点是移动Web开发的优点。
在iOS中,苹果强制全部浏览器必须使用自家的Webkit内核,因此全部浏览器的体验很是一致,出问题的话也都出同样的问题,改问题也比较容易点。幸运的是iOS把它优化得十分不错,因此更多的程序员都喜欢作iOS下的前端开发。
相比iOS,Andorid可谓是百花齐放,各个浏览器都个性十足,好比UC浏览器,它包含不少功能:
每一个浏览器优化的功能都是一个陷阱,均可能致使应用没法正常工做。最多见的是浏览器自带的手势与页面手势冲突,致使页面手势没法正常工做,又或者浏览自带一些悬浮按钮对页面上的按钮产生了遮挡等等。
一些不太容易碰见的异常就可能与应用场景有关。好比我以前作的一个功能,在页面初始化时须要使用JS记录页面运行一些状态参数,因为UC浏览器的网页预读功能,它会自动识别当前页面的下一页
按钮,而后预读下一页而且提早渲染与处理JavaScript。这就致使页面状态记录错乱,由于在用户没有真实看到下一页时,实际上状态参数已经改变为下一页的状态了。这个问题最后是在下一页
按钮上加上了disabled
样式解决的,若是<a>
有disabled
样式或属性,那么UC在预读时就会忽略掉。
再好比 APP下载连接被看成广告过滤掉等等,相似这样的问题还有不少,都是由于浏览器自身特性致使的兼容问题。
浏览器差别除自身功能特性以外,还有不少实现差别致使的兼容问题,这样的问题是最坑爹的。为何说坑爹呢?看下面几个例子:
软键盘
文本框
<video>
标签中也有体验,好比UC或QQ;position:fixed
前些天又总结了一篇博文《微信内置浏览器WebApp开发,踩坑》也是有关浏览器踩坑的问题。
这些在正常状况下,都认为没有问题的地方,每每都会出现各类奇葩的兼容问题,而正是这些问题耗费了咱们大量的精力和时间。
如今回过头看之前遇到的一些兼容问题,随着Android版本、Webkit引擎和各类浏览器的升级,不少兼容都在从底层被解决,而且对标准的支持也愈来愈好。
之前我总是会纠结是否须要去解决一些老旧设备遇到的兼容问题,通过这么长时间,对这个问题我也找到了一个本身的答案:“应该大胆的使用更高级,能带给用户更好体验的特性,不要顾虑太多,移动技术发展得太快,快到等你作完这些兼容以后,这些设备已经被淘汰了。”
和你们分享一组内部的统计数据:采样12万个,Android系统,Andorid 2.x 占15.47%,Android 4+ 占82.12%。
在视觉篇中提到的:维基百科中List of displays by pixel density详细的记录了各种设备的尺寸和分辨率。更正:维基百科页面被删除,缘由不明。使用两个替代方案查询设备的尺寸和分辨率: