首页 > 代码库 > 移动web
移动web
移动web的基础知识(the basic knowledge of mobile web)
·px:css pixels逻辑像素,浏览器使用的抽象单位,根据不同的设备,会变大或者变小
iphone5的分辨率是640*1136(使用的物理像素)。320px*568px(使用的逻辑像素)
·dp,pt:device independent pixels设备无关像素,不会随设备的变化而变化的大小
·dpr:devicePixelRadio设备像素缩放比
平面上:1px = 2*2*dp 纬度上:1px = 2*dp
dp与px之间的关系是通过dpr进行控制的,计算公式为1px = (dpr)*(dpr)*dp。因为iphone5的dpr=2,所以iphone5的分辨率是320px*568px,也可以说是640dp*1136dp。
所以640px*1136px的图片不能在iphone5上完全展示。
·DPI:打印机每英寸可以喷的墨汁点(印刷行业)
·PPI:屏幕每英寸的像素数量,即单位英寸内的像素密度
在计算机显示设备参数描述上,二者意思表达的都是单位面积内的像素密度。以iphone5为例子进行计算说明
ppi = √(11362+6402)/4 = 326ppi(视网膜Retina屏),计算ppi的时候应该用物理像素计算
ppi越高,像素数越高,图像越清晰。但可视度越低(小),系统默认设置缩放比越大(比如:pc的分辨率越高,则桌面上的icon越小)
表1
ppi 默认缩放比 |
ldpi | mdpi | hdpi | xhdpi |
120 | 160 | 240 | 320 | |
0.75 | 1.0 | 1.5 | 2.0 |
Retina屏(高清屏):dpr都是大于等于2
以iphone5为例设备分辨率转为像素分辨率:官方指导iphone5的设备分辨率为1136*640dp,根据公式得到其为326ppi,326ppi属于retina高清屏,根据表1得到默认缩放比dpr=2,再根据公式1px = dpr2*dp得到iphone5的屏幕为320*568px
·Viewport
pc端的页面会把整个页面渲染在移动端的一个viewport里面,来保证可以在移动端看到页面的全貌。
ios的viewport普遍为980px,安卓的viewport可能有640px,1000px,1200px等等
手机浏览器默认为我们做了两件事情:
一 页面渲染在一个980px(ios)的viewport中
二 页面渲染在viewport中后,进行缩放。
这样做的目的可以防止屏幕过小时排版的混乱,所以在pc页面在移动端进行渲染时,虚拟了一个viewport来保证排版的正确。
viewport可以细分为两层,一层是visual viewport(视图viewport,控制窗口缩放的大小),一层是layout viewport(布局viewport,这个viewport就指的移动端浏览器默认的viewport,如ios的980px)
设计移动web一般不使用默认的980px布局的viewport,原因有以下几点:
1,宽度不可控制,不同系统不同设备的默认值都可能不同
2,页面缩小版显示,交互不友好
3,链接有时不可点
4,有缩放,缩放后有滚动
5,font-size为40px才等于PC上的12px同等物理大小,不规范
可以使用meta标签改变默认的viewport
·meta标签
<meta name="viewport" content="width=device-width,initial-scale=1.0"> 保证默认viewport的宽度始终等于设备宽度
width:设置布局viewport的特定值(“device-width”)
inital-scale:设置页面的初始缩放
minimum-scale:最少缩放
maximum-scale:最大缩放
user-scalable:用户能否缩放
移动页面的最佳设计比为:布局viewport = 设备宽度 = 度量viewport。因此meta标签最佳设置为
<meta name=‘viewport‘ content=‘width=device-width,initial-scale=1,user-scalable=no‘
·设计移动web
方案一:根据设备的实际宽度来设计(常用)
手机宽320px,就拿320px设计
方案二:1px = 1dp
缩放0.5,根据设备的物理像素dp等于抽象像素px来设计。1px边框和高清图片都不需要额外处理
高效的移动web布局(efficient mobile CSS layout)
PC端的页面常使用的两种布局为固定布局和流体布局,其中固定布局占主导。
但是移动端页面无法使用固定布局,因为移动设备的屏幕及分辨率非常多,所以在移动端经常使用响应式布局及flex弹性布局。
·使用flex弹性盒子布局,实现根据元素个数不同,自动填充容器,以下是flexbox的几种常用布局模式
flex等比划分
父容器 display:-webkit-flex 子容器1 flex:1(等比占1/3) 子容器2 flex:2(等比占2/3)
flex混合划分
父容器 display:-webkit-flex 子容器1 flex:1(等比占1/3) 子容器2 flex:2(等比占2/3) 子容器3 width:100px;
这种布局方式在移动web的应用场景更加广泛,比如图文混合的情况,一般图片为了保证清晰度不宜放大,所以图片采取固定宽度,而文字则可以根据容器的大小而变化
不定宽高的水平垂直居中
父容器 { display:-webkit-flex;justify-content:center;align-items:center}
flex兼容性
1,ios可以使用最新的flex布局;2,android4.4一下,只能兼容旧的flex布局;3,android4.4以上,可以使用最新的flex布局
·响应式设计
使用百分比布局
仅仅使用媒体查询来适应不同的固定宽度设计,只会从一组css到另一组css的切换。两种之间的没有任何平滑渐变(比如使用media为iphone和ipad air都设置了样式,但是二者之间的ipad mini没有设置样式,这样会导致ipad mini上的样式错乱)
弹性图片
图片也使用百分比,无论什么情况下,都全包在图片的元素宽度范围内,以最大的宽度同比完整的显示图片。如img{max-width:100%}
重新布局,显示与隐藏
当页面达到手机屏幕宽度的时候,很多时候就要放弃一些传统的页面设计思想。尽量保证页面的简单、整洁。可以采取下述方法进行处理
1,同比缩小元素的尺寸;2,调整页面结构布局;3,隐藏冗余的元素;
经常需要切换位置的元素使用绝对定位,减少重绘,提高渲染性能
响应式的利弊
1,根据响应式的设计理念,一个页面包含所有设备不同屏幕的样式和图片,当一个移动设备访问一个响应式的页面,就会下载PC、ipad、iphone等不同设备对应的样式,而这些样式却是冗余的,没有必要的。
2,虽然响应式的设计性能不是最优的,但是却可以减少重复开发,一个样式同时适配多端。
·移动web特别样式处理
高清图片
比如100px*100px的图片在Retina屏幕上渲染,则是在200dp*200dp的屏幕上渲染的,所以会拉大。所以在移动web页面上渲染图片,为了避免图片产生模糊,图片的宽高应该用物理像素单位渲染,即是100*100的图片,应该使用100dp*100dp
width:(w_value/dpr)px; height:(h_value/dpr)px
一像素边框
Retina屏幕下的问题,根本原因是border:1px使用2dp进行渲染
由于border:0.5px的这种解决方式在安卓上不适用,所以一般可以采用scale(0.5)进行一下缩放
·相对单位rem
为了适应各大屏幕的手机,px不能根据尺寸的大小而改变,使用相对单位更能体验页面兼容性
em:根据父节点的font-size为相对单位;这个单位在多层嵌套下,会变得很困难
rem:根据html的font-size为相对单位;这个单位更加能作为全局统一设置的度量
为了适应各大手机屏幕,rem的基值设置为rem=screen.width/20
html{font-size:32px} iphone5
@media (min-device-width:375px){html{font-size:37.5px}} iphone6
@media (min-device-width:414px){html{font-size:41.4px}} iphone6 plus
一般font-size不使用rem等相对单位作为单位,因为字体的大小是趋于阅读的实用性的,并不适合于排版布局。
·多行文本溢出
单行文本溢出 .inaline{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
多行文本溢出 .inmoreline{display:-webkit-box!important;overflow:hidden;text-overflow:ellipsis;word-break:break-all;-webkit-box-orient:vertical;-webkit-line-clamp:3;} -webkit-line-clamp的值表示在第几行用“...”表示溢出
终端交互优化(interactive optimization in mobile web)
移动web页面上的click事件响应都要慢上300ms。是因为移动设备访问的web页面都是pc上的页面,在默认viewport(980px)的页面往往都是需要“双击”或“捏开”放大页面以看清页面。而正是为了确认用户是“双击”还是“单击”。safari需要个300ms的延迟来判断,而后来的iphone也一直延续这种设计,而借鉴iphone的android也沿用这样的设计。于是“300ms的延迟”成为了一道规范。
使用tap事件代替移动web中的click事件。使用touch事件进行模拟。
tap事件在移动端的点透的bug,这个bug和300ms的延迟有关
移动端click事件的触发过程:touchstart,touchend....300ms......click触发
移动端点透发生的过程:touchstart导致蒙层消失,touchend冒泡到btn上.....300ms.....btn的click触发
tap透传的解决方案
1,使用缓动动画,过渡300ms的延迟
2,中间层dom元素的加入,让中间层接受这个‘穿透’事件,稍后隐藏
3,‘上下’都使用tap事件,原理上解决tap透传事件(但不可避免原生标签的click事件,比如<a>)
4,使用fastclick库或者最新的zepto
Touch基础事件的常用属性
-touches:跟踪触摸操作的touch对象数组
-targetTouches:特定事件目标的touch对象数组
-changeTouches:上次触摸改变的touch对象数组
var touchHandler = function(e){
var type = e.type;
//touchend的touches和targetTouches为空,
if(type !== ‘touchend‘){
var pos = {
x:e.touches[0].clientX,
y:e.touches[0].clientY
}
switch(type){
case ‘touchstart‘:break;
case ‘touchmove‘:event.preventDefault();break;//安卓4.4.4.0的bug,只触发touchstart,和一次touchmove,touchend不触发。加入preventDefault会解决这个bug,但是会导致阻止默认事件,比如scroll,导致页面不滚动。
case ‘touchend‘:break;
}
}
}
touch.js
var touch = {
startX: 0,
startY: 0,
endX: 0,
endY: 0,
touchStart: function (event) {
var touchPoint = event.touches[0];
this.startX = touchPoint.pageX
this.startY = touchPoint.pageY
this.endX = 0
this.endY = 0
},
touchMove: function (event) {
var touchPoint = event.touches[0];
endX = touchPoint.pageX
endY = touchPoint.pageY
},
isSwipe: function (strX, endX, strY, endY) {
var flag = false;
if (endX && endY) {
flag = Math.abs(endX - strX) > 80 || Math.abs(endY - strY) > 80
}
return flag;
},
swipeDirection: function (strX, endX, strY, endY) {
var swipeDirection = Math.abs(endX - strX) > Math.abs(endY - strY) ? ((endX - strX) > 0 ? "Right" : "Left")
: ((endY - strY) > 0 ? "Down" : "Up");
return swipeDirection.toString();
}
};
var touchEvents = {
touchstart: "touchstart",
touchmove: "touchmove",
touchend: "touchend",
/**
* @desc:判断是否pc设备,若是pc,需要更改touch事件为鼠标事件,否则默认触摸事件
*/
initTouchEvents: function () {
if (!isAppBrowser()) {
this.touchstart = "mousedown";
this.touchmove = "mousemove";
this.touchend = "mouseup";
}
}
};
function isAppBrowser() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var isAppBrowser = false;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
isAppBrowser = true;
break;
}
}
return isAppBrowser;
}
移动web效果之弹性滚动
当客户端的页面滚动到顶部或者底部的时候,滚动条会收缩并让我们多滑动一定距离。通过缓冲反弹的效果,带给用户良好的体验。这种效果一般在原生APP中出现,移动web页面也可以做到,但滚动有几种情况需要考虑:
-body层滚动:(系统特殊化处理)自带弹性滚动,overflow:hidden失效,GIF和定时器暂停
-局部滚动:没有弹性滚动,没有滚动惯性,不流畅
局部滚动开启弹性滚动方法:body{overflow:scroll;-webkit-overflow-scrolling:touch;}。但是android不支持原生的弹性滚动,即上述样式没有生效,可以借助第三方库iScroll来实现。
移动web效果之下拉刷新
顶端下拉一小点的距离,页面弹性滚动向下
移动web效果之上拉加载
使用scroll事件,而不是touch事件(android有bug)
移动web