先介绍一下项目环境,前端工具使用fis-plus,主要使用了zepto插件。整体架构比较简单。
在这里我们不讨论viewport布局(使用viewport貌似坑会少很多,但是由于条件限制,有时只能使用原始方法开发),下面进入正题:
零、调试工具
推荐大家在调试移动端页面时使用chrome的toggle device mode。
在此模式下可以随意切换市面上的各种主流机型。不过真机与模拟环境还是有一定差距,在后期测试阶段你将会深切地感受到这一点,木哈哈哈。
一、布局。
PC端和移动端的布局的思路还是比较不同的。如果最初没有考虑好移动端布局的思路,在后期兼容性等完善过程中将会超级痛苦。
在PC端我们很常见的一种布局思路如下:将网页主题设为固定宽度,居中,并定义最小宽度,可适配各种大小的PC端屏幕。由于PC端可视范围较大,所以上述方法可行,但是移动端完全不同,移动端的屏幕本身就比较小,所以我们必须全部利用起来。移动端的页面一般来说结构都会比较简单,下面分结构介绍两种布局:
(1)居中
一般banner或者按钮等元素都会定义为居中布局。在ps中量好外边距后,直接给元素设置margin,如:margin: 0 10px; 无需设置宽度,元素会自动撑开,且在任何屏幕上都会有相同10px的左右外边距。
(2)多个元素水平排列
比较复杂一点的,如上图中第一排的新闻、小说等图标是怎么样布局的呢?经过简单的计算,每个元素都定义为16%的宽度,这样总共是16%*6=96%,剩下的4%再给两边的元素各加2%的外边距就ok了。
如果你想实现更加完美的效果,比如使图片跟随手机屏幕的大小变化,则可以给图片设置相对宽度,并使高度自动伸缩,则可以达到以上效果。
二、像素
由于现在需要多移动端使用的是retina视网膜屏幕,所以在看页面设计图时,需要按照原型图尺寸的一半进行长度赋值。这里就会引出一个十分蛋疼的问题:当设计图有1px的线条或border时,我们该怎么办!
有人说了,iOS 8 和 OS X Yosemite 支持 0.5px 的边框。我只能说呵呵,光有两个系统是木有用的。
告诉大家一个目前来看最佳方案:
伪类 + transform
原理是把原先元素的 border 去掉,然后利用
:before
或者:after
重做 border ,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。.test:before {
content: " ";
position: absolute;
left: 0;
top: 0;
100%;
height: 1px;
border-top: 1px solid #dadad9;
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleY(0.5);
-ms-transform: scaleY(0.5);
transform: scaleY(0.5);
}
在调试兼容性的过程中可能会遇到各种麻烦,不过耐心的慢慢调试,页面一定会实现完美的1像素,你也会炼成钛合金像素眼。
三、点击事件
在移动端的点击事件中,如果使用我们异常熟悉的click事件,确实不是一个最佳方案。因为click事件因为种种历史原因,有300ms的延时。所以我们可以使用tap事件。
使用tap事件你可以能在开发过程中又会遇到一个蛋疼的问题:点击穿透现象。如果页面上弹出一个dialog,并且,在确定按钮的下一层的这个位置正好有一个绑定了点击事件的元素,那就热闹了,点击一下,可以触发两个事件。
如何避免呢?介绍两个简单的方法,一个是将tap换成click,或者在事件最后加上preventDefault();防止冒泡。
四、空div在低端安卓显示不出来问题
在开发过程中发现了这样一个奇怪的问题:有些无内容的容器已经设置了高度与宽度,也设置了背景图,但是在安卓低端机上就是无法显示。目前解决方案自我感觉非常山寨:将高度或宽度换成对应的padding,将容器撑起来。虽然山寨,但是实践验证了,这种方法非常好用。
五、外边距合并
还是安卓的低端机上的问题,(貌似在低版本的PC端浏览器也会出现,但是很少遇到),外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。
这个情况下对元素使用overflow:hidden;就会消除外边距的合并,百试百灵。
六、display使用table-cell等表格布局导致页面错乱。
仍然是安卓的低端机上的问题。在开发页面过程中我也很少使用表格布局,出现问题的情况会比较多。正常可以使用inline-block,配合float:left;一般不会出现问题。
七、缓存
html5中的web storage分为localStorage与sessionStorage。
localStorage用于持久化的本地存储。如果用户不主动清空数据,数据永远不会过期。
sessionStorage用于本地存储一个会话中的数据,这些数据只有在同一个会话中的页面才能访问,当回话结束时,数据也随之销毁。因此,sessionStorage不是一种持久化的本地存储,仅仅是绘画级别的存储。
八、文字垂直居中
在PC端开发时,比较常用的方法为设置相同的height与line-height。但是在移动端,如果在某些容器中使用此类方法,你会发现文字在某些机型上跑偏了二里地。
从这个现象可以看出,移动端的浏览器对于css的解析确实没有PC端完善。原来以为IE三兄弟(IE6、IE7、IE8)是最坑的了,没想到被移动端的无数个兄弟完爆了。
言归正传,如何解决上述问题呢?微信采用的是在需要垂直居中的容器外套一层div,使用盒模型强制将其内部容器垂直居中。具体实现可参见 http://weui.github.io/weui 微信样式库。
另外就是在input中尽量不使用line-height,避免引起placeholder垂直位置偏移。
九、页脚元素避免使用绝对定位。
移动端页面经常会有页脚放置copyright或logo的需求,这时千万不要使用position:absolute;bottom: 20px; 这种坑爹布局。如果这个页面存在输入需求,当调起软键盘时,你定义的这个绝对位置元素就会蹦跶到软键盘上方的页面上。
可能你会觉得,如果页面没有输入框,就不存在这种问题了吧。too young too naive。世界上还有一种奇葩机型,返回键是设置的在页面底部的啊!!!你只要一写绝对定位在页脚底部的布局,百分百中招啊!
所以我们尽量不要使用上面的那种布局,如果硬要达到距离页面底部固定高度的效果,可以动态计算页面最小高度并进行赋值~