移动开发总结

参与了几个移动端的 web 开发,在团队合作中与在开发中,踩了一些移动开发的坑,希望这篇博文可以让移动开发人员
在开发 web 时有所启发,同时组内师弟师妹在做项目时避免类似的坑。

##切图
问过在网易实习的师兄师姐,在页面重构时候一般需要自己切图与开发一手完成,但是怎样才能快速地切出自己想要的
图呢?这里推荐一个插件 CutterMan 。可以帮助你快速切图,并切好两倍三倍图。

##我对像素的一些理解
其实像素分为两种,一种是 CSS 像素,它是 WEB 开发人员抽象出来的一种概念,另外一种是设备像素,它是设备的物理
像素,只有当 dpr(设备像素/css 像素)等于 1 的时候,两者才相等。那么到底为什么图片在高清屏幕上会模糊呢?
原因在于在高清屏幕上,物理像素更多,一个 CSS 像素有多个物理像素来表示,而一个 CSS 像素用一个物理像素表示
才会高清,现在多个物理像素,计算机只好就近取色来填充 “多余” 的物理像素,导致相片模糊。
下图是同样是 1px 在不同的屏幕下的表示。

[图片来自 http://caibaojian.com/.]

##Viewport
viewport 是由苹果开发出来的,目的就是为了适配移动端页面。这是因为苹果开发出 retina 屏幕,屏幕大小不变而像
素增加一倍,与过去的网页不能平稳过度,因为原来 960 px 的网页导航栏为 60%,解析出来就是 576 px,但是遇到了
320 px 的手机屏幕,解析成了162 px,但是字体设置又用了 px,那么字体就无法友好显示了,所以开发出 viewport,
分为两个 visual viewport 和 layout viewport。
layout viewport 是由浏览器厂商规定的,一般是 980 px,现在有了layout viewport,页面在手机上就像在 980 px 的屏幕上显示一样,手机可以通过滚动条来看网页,但是如果我们需要网页去除滚动条满屏显示(320 px),那么因为 layout viewport 是 980 px,这样的网页因为缩放,看起来非常小,所以才有了后来的 width=device-width 这个值。

##自适应
自适应是移动开发最注意的点之一,为了良好的用户体验,下面的三种方法都有各自的使用场景。一般来说自适应需要
关注三个点:字体、高宽统一、图像。

###高度一定,宽度自适应
这个方法其实体验很好,自动填充空白。但是有几个点需要注意,这是一个适应窄宽度的布局,但是在屏幕变宽的时候,
却需要比较大的图像才会不至于拉伸模糊,这一点比较矛盾。像手机新浪采用的方法就是高度固定,宽度使用百分比的
自适应布局方案。手机新浪就是采用了这种方法。

###固定宽度,viewport 缩放
这个可以完全按照设计稿,使用 px,em,PC 端即可完成大部分测试,手机端考虑对齐问题。在实践上,设计稿,页面
宽度, viewport 值采用同一宽度值,但是一般来说,这个并不是最优解决方案,因为一般来说移动端都需要适应大屏
手机与小屏手机。

###利用rem布局
使用 rem 是让那些页面中需要弹性变化的元素进行布局。根据自身的项目经验,rem 确实方便快速。
手机腾讯网就是采用了这种方式,对于需要弹性变化的元素都采用 rem 进行布局。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var dpr, rem, scale;
var doc = document;
var docEl = doc.documentElement;
var meta = doc.querySelector('meta[name="viewport"]');

dpr = window.devicePixelRatio || 1;
rem = docEl.clientWidth * dpr /10;
scale = 1 /dpr; //scale 与 dpr 的关系的倒数

//设置 viewport,根据 scale 进行缩放,达到高清
meta.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',inital-scale='+ scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');

//设置 data-dpr 属性,留做设置字体用
docEl.setArribute('data-dpr', dpr);
//设置根元素的字体大小
docEl.style = 'font-size='+ rem + 'px';

但是缺点是设计稿中的 px 与开发中的 rem 的换算比较困难,这里我在项目中使用的是 cssrem 这个插件,可以帮助
换算他们的值。
最后,其实代码中的 scale 是用于解决 border:1px 问题的,因为 2 倍稿中的 1px 相当于 1倍稿中的 0.5 px,
我们为了解决这个问题,可以使用 js 动态设置 scale 来达到目的,如果你不想使用 js ,那么可以使用 CSS hack。

1
transform: scaleX(0.5); //画出 2 倍稿中的 1px,即 1 倍稿中的 0.5 px。

有人会有疑问,如果设置了 scale ,那么字体大小页面布局不也就变化了吗?是的没错,所以上面的 rem 布局可以解决
这个问题,因为如果布局使用的是 px 做单位,的确会有影响,但是使用 rem 就不会,布局只会与根元素的 font-size
有关,同时字体使用 css media 与根元素的 data-dpr 来设置,就没有问题了。

###总结
在移动端开发,总的来说还是要按照设计稿的要求采取不同的解决方案。下面的这个 meta 标签是移动开发必备,
不管你有没有理解 ppi,dpr 等知识,它可以让你忽略设备的干扰,直接开发。

1
<meta name="viewport" content="width=device-width,user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

以上说的三种方法都是在 viewport 的基础上,为了页面的元素的宽度适应屏幕而做出的方案。

##图片
因为位图有可能会被拉伸(PPI的问题),所以我们得使用高清图。问题是需要多高清?一般有两种做法:

  1. 准备 1/2/3 倍图。
  2. 放弃 1 屏机,全部使用 2 倍图。
    两个方法来说,第一个方法比较繁琐,第二个方法的流量优化,滚动加载手段就会显得比较重要。
    ##字体
    如果是使用 REM 布局,那么字体就应该使用 px 等单位。因为点阵字体一般是 14 或 16 这样的数字,但是如果使用
    rem 单位,就会有可能会出现 13/15 这样怪异的尺寸,不利于字体渲染。但是遇到像标题这样需要大字号的可以使用
    rem。在腾讯首页是几乎全部字体都使用了 rem 单位。
    比较好的做法是根据 dpr 来设置字体:
    1
    2
    3
    4
    5
    6
    [data-dpr=1] {
    font-size: 16px;
    }
    [data-dpr=2] {
    font-size: 32px;
    }

##附录:值得注意的点
1.显示时候的地址栏的隐藏。

1
2
3
setTimeout(function(){
window.scrollTo(0, 1);
},0);

2.打开软键盘:

1
<input type="tel">

3.click事件有 300ms 的延迟,运用 fastclick ,还可以防止穿透。
4.在使用动画的时候,尽量使用 transform: translate3d() 可以开启硬件加速。
5.weinre 调试大法:移动端的调试困惑了我好久。
很多人推荐使用 weinre,我自己配合 UC 二维码 浏览器插件使用。

1
2
3
4
5
6
npm install -g weinre
weinre --boundHost -all- --httpPort 8081

打开 localhost:8081

edpm start

项目:
Tour4U
2016 协同招新网页

参考资料:
移动适配
移动开发
移动开发的20个要点

传送门:
移动开发资源集合
移动前端不得不了解的html5 head 头标签