首页 > 代码库 > 移动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