手记

笔记——Hello,移动WEb

一.移动Web的基础知识
1.Pixel像素基础

iphone5
640 X 1136 物理像素
320 X 568 逻辑像素

px: Css pixels逻辑像素,浏览器使用的抽象单位
dp,pt: devide independent pixels设备无关像素物理像素固定
dpr: devidePixelRatio 设备像素缩放比

计算公式: 1 px = (dpr)^2 X dp

为什么iphone5是320px X 568px*?
一> 因为dpr = 2

平面上:1px = (2)^2 X dp
纬度上:1px = 2 X dp

—> 640dp X 1136 dp
= 320px X 568px

DPI: 打印机每英寸可以喷的墨汁点(印刷行业)
PPI: 屏幕每英寸的像素数量,即单位英寸内的像素密度

目前,在计算机显示设备参数描述上,二者意思表达的是一样的。

计算公式:以iphone5(4英寸)为例子
ppi = √(1136^2 + 640^2) / 4 = 326 ppi (视网膜Retina屏)
注意:单位为硬件像素,非px

PPI越高,像素数越高,图像越清晰
但可视度越低(小),系统默认设置缩放比越高(大)

  ldpi mdpi hdpi xhdpi
默认缩放比dpr 0.75 1.0 1.5 2.0
Retina屏(高清屏): dpr都是大于等于2
2.Viewport视图

手机浏览器默认为我们做了两件事情
一:页面渲染在一个980px(ios)的viewport
二:缩放

为什么渲染时,要有viewport?
—>为了排版正确

visual viewport (度量/视口)

== 窗口缩放salce

<meta   name = '"viewport"  content ="width = devide - width">
window,innerWidth   //…[visual` viewport](会窗口变化)
screen.width                    //….[屏幕宽度](固定值)

layout viewport (布局viewport)

body{width:320px}
document.body.clientWidth       //…[layout viewport]

注意:指,layout viewport,不是原页面的大小,
如:ios默认viewport是980px

window,innerWidth / document.body.clientWidth       //1…(默认缩放比dpr)  

为什么不使用默认的980px的布局viewport

  • 宽度不可控制,不同系统不同设备的默认值都可能不同

  • 页面缩小版显示,交互不友好

  • 链接点不可点

  • 有缩放,缩放后又有滚动

移动font-size为40px等于PC上12px同等物理大小,不规范

3.Viewport_Meta 标签
<meta   name = '"viewport"  content ="name = value, name = value">
  • width - viewport的宽度[pixel_value |device-width]
  • height - viewport的高度[pixel_value |device-height]
  • initial-scale - 初始的缩放比例[float_value]
  • maximum-scale - 允许用户缩放到的最大比例
  • minimum- scale (/scalbujue) - 允许用户的最小缩放值
  • user-scalable - 用户是否可以手动缩放 [yes | no]
    <meta   name = '"viewport"  content =" width = 320">
    <meta   name = '"viewport"  content =" width = devide - width">

    width = devide – width ——> layout viewport = 设备宽度

<meta   name = "viewport"  content ="initial - scale = 1.0">

initial – scale自带width = devide – width ——> 度量viewport = 布局viewport

移动web最佳viewport设置

<meta   name = '"viewport"  content =" width = devide - width, initial - scale = 1,user – scale = no">

布局viewport = 度量viewport = 设备宽度

4.Viewport_coding

Viewport

方案一:根据设备的移动宽度来设计(常用)

手机宽度320px,我们就拿320px设计。

方案二:1px=1dp

缩放0.5。根据设备的物理像素dp等于抽象像素px来设计。1px边框和高清图片都不需要额外处理。

二.高效的移动Web布局
1.Flexbox弹性盒子布局

根据元素个数不同,自动填充容器

.nav {…; display: -webkit-flex;  / *display: -webkit-flex 标示使用弹性布局*/}
.item {…; flex:1  /**flex: num 占容器的比例/}

Flex等比划分

.item1 {…; flex:1}          /*/占容器1/(1+2) */
.item2 {…; flex:2}          /*占容器2/(1+2) */

Flex混合划分

.item1 {…; width: 100px}   /*占容器100px               多用于图片*/
.item2 {…; flex:2}          /占容器2/(100%-100px)    多用于文字*/
.item3 {…; flex:1}          /占容器1/(100%-100px)    多用于文字*/

在移动web的应用场景更加广泛
不定宽高的水平垂直居中

.myoff_wrapper 
{
position: absolute;
top: 50px;
left: 50px;
z-index: 3;
-webkit-transform: translate(-50%, -50%);
border-radius: 6px;
background: #fff;
}

【Flexbox版】不定宽高的水平垂直居中

.parent 
{
justify-content: center;                        /*子元素水平居中*/
display: -webkit-flex;
}
扩展知识

引用:Flex 布局教程:语法篇
作者: 阮一峰
日期: 2015年7月10日

Flex 布局是什么?

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为 Flex 布局。

.box{
  display: flex;
}

行内元素也可以使用 Flex 布局。

.box{
  display: inline-flex;
}

Webkit 内核的浏览器,必须加上-webkit前缀。

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。

基本概念

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为
Flex 项目(flex item),简称"项目"。

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。

主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end

交叉轴的开始位置叫做cross start,结束位置叫做cross end

项目默认沿主轴排列。
单个项目,
占据的主轴空间叫做main size
占据的交叉轴空间叫做cross size

容器的属性

以下6个属性设置在容器上。

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

项目的属性

以下6个属性设置在项目上。

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self
2.响应式设计

兼容性

  • ios可以使用最新的flex布局
  • android4.4以下,只能兼容旧版的flexbox布局
  • android4.4及以上,可以使用最新的flex布局
新flex布局 旧flexbox布局
display:-webkit-flex; display:-webkit-flex-box;
-webkit-flex:1; -webkit-flex-box:1;
justify-content:center; box-pack:center;
align-items:center; box-align:center;

媒体查询:

- screen(屏幕)
- print(打印机)
- handheld(手持设备)
- all(通用)

常用媒体查询参数

  • width —— 视口宽度
  • height —— 视口高度
  • devide-width —— 设备的宽度
  • devide-height —— 设备的高度
  • orientation: 检查设备处于横屏(landscape)还是竖屏(portrait)

设计点一:百分比布局

仅仅使用媒体查询来适应不同的宽度设计,
只会从一组css到另一组css的切换。
两种之间的没有任何平滑渐变。
当没有命中媒体查询时,
表现就会变得不可控制(滚动,换行)。

设计点二:弹性图片

<div class="img"><img scr="xxx.jpg"/></div>
.img{max-width:100%;}
无论何时,都全包在图片的元素宽度范围内,
以最大的宽度同比完整的显示图片。

设计点三:重新布局,显示和隐藏

当页面达到手机屏幕宽度的时候,
很多时候就要放弃一些传统的页面设计思想。
力求页面简单,简洁。

  1. 同比例缩减元素尺寸
  2. 调整页面结构布局
  3. 隐藏冗(rong3)余的元素
    经常需要切换位置元素使用【绝对定位】,
    减少重绘画提高渲染性能。

关于响应式设计的思考

根据响应式设计的理念,
一个页面包含所有设备不同屏幕的样式和图片,
当一个移动设备访问一个响应式的页面,
就会下载PC,笔记本,ipad等不同设备对应的样式。
而这些样式却是冗余的,完全没有用。

权衡利弊

  • 弊:性能不是最优。
  • 利:减少重复开发
    3.移动Web特别样式处理

高清图片
在移动web页面上渲染图片,为了避免图片产生模糊,
图片的宽高应该用物理像素定位渲染,即100 X 100的图片,
应该所有100dp X 100dp。
width:(w_value/dpr)px;
height:(h_value/dpr)px;

一像素边框
同样是retina屏幕下的问题,
根本原因: 1px使用2dp渲染。
border:0.5px /不可用!仅仅ios8可以用/
正确用法: sacleY(.5)

.sidebar .folder li {
/*border-top: 0.5px solid #ddd;*/
padding: 8px 0 8px 15px;
color: #7c7c7c;
position: relative;
}
.folder li+li:before {
position: absolute;
top: -1px;
left: 0;
content: " ";
width;100%;
height:1px;
border-top:1px solid #ddd;
-webkit-transform:scaleY(.5);
}

相对单位rem
为了适应各大屏幕的手机,px略显固定,
不能根据尺寸的大小而改变,
使用相对单位更能体验页面即时性。

  • em:是根据父节点的font-size为相对单位
  • rem:是根据html的font-size为相对单位

em在多层嵌套下,变得非常难以使用
rem更加能作为全局统一设置的度量

rem的基值设置多少好?
回归我们的目的:为了适应各大手机屏幕

rem = screen.width / 20; (screen.width / 10)

/*默认320px; 320px/10*/
html{font-size: 32px;}
/*iphone 6*/
@media (min-devide-width: 375px) {
html{font-size: 37.5px;}
}
/*iphone 6 plus*/
@media (min-devide-width: 414px) {
html{font-size: 41.4px;}
}

如(iphone5)html:32px;(rem基值)—— div:64px 64px;—— 2rem 2rem

换算公式:width:px/rem基值;height:px/rem基值。

不使用rem的情况:font-size
一般来讲font-size是不应该使用rem等相对单位的。
因为字体的大小是趋向于阅读的实用性,
并不适合于排版布局。
同理趋向于一些固定的元素的特性。
我们不使用rem而改为使用px去确保
在不用屏幕上表现一致(跟rem的目的相反)。

多行文本溢出…

/*单行文本溢出…*/
.inaline {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis(省略);
}
/*多行文本溢出…*/
.intwoline {
display: -webkit-box !portant;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertial;
-webkit-line-clamp: 2;      /*显示行数*/
}

单行文本溢出,对title类的使用非常多,
而多行文本溢出,在详情介绍则用的比较多。

三.终端交互优化
1.介绍

在移动设备上没有了鼠标输入,
hover等一些鼠标事件不再生效。
取而代之的是更加人性化的触摸事件(touch)。
PC上的惯性思维,是时候要转换一下。

终端交互优化
对click事件say no tap事件基础
弹性滚动 touch触摸事件
上拉刷新 下拉加载
2.Tap基础事件

300毫秒的故事
移动web页面上的click事件响应都要慢上300ms。
假定这么一个场景。用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。
于是,300 毫秒延迟就这么诞生了。

300ms延迟怎么办?
使用Tap事件代替click事件。

自定义Tap事件原理:
在touchstart、touchend是记录时间、手指位置,
在touchend时进行比较,如果手指位置为同一位置
(或允许移动一个非常小的位移值)且时间间隔较短
(一般认为是200ms),且过程未曾触发过touchmove,
即可认为触发了手持设备上的“click”,一般称它为“tap”。

移动框架库Zepto.js****

(按钮)click事件触发过程:
touchstart —— touchend —— 300ms —— click触发
(按钮前加蒙层)点透发生过程:
touchstart —— touchend蒙层消失 —— 300ms —— target为btn,click触发

Tap透传的解决方案

  1. 使用缓动动画,过渡300ms的延迟
  2. 中间层dom元素的加入,让中间层接受这个“穿透”事件,稍后隐藏
  3. “上下”都使用tap事件,原理上解决tap透传事件(但不可避免原生标签的clisk事件)
  4. 改用Fastclick的库(听说最新的则zepto已经fixed掉这个bug)
  5. 触摸touch
    触摸才是移动设备的交互的核心事件。

touchstart:手指触摸屏幕触发(已经有手指放屏幕上不会触发)。
touchmove:手指在屏幕滑动,连续触发。。
touchend:手指离开屏幕时触发。
touchcancel:系统取消touch时候触发(不常用)。

BUG: Android只会触发一次touchstart,一次touchmove,touchend不触发。
解决方案: 在touchmove中加入:event. preventDefault()可fixedBug。(调用事件可以阻止滚动)
但注意: event.preventDefalut()会导致默认行为不发生,如scroll,导致页面不滚动。

除常见的事件属性外,触摸事件包含专有的触摸属性(用于跟踪触摸)。

touches:跟踪触摸操作的touch对象数组
targetTouches:特定事件目标的touch对象数组
changeTouches:上次触摸改变的touch对象数组

每个touch对象包含属性:

clientX:触摸目标在视口中的x坐标。
clientY:触摸目标在视口中的y坐标。
identifier:标识触摸的唯一ID。
pageX:触摸目标在页面中的x坐标。
pageY:触摸目标在页面中的y坐标。
screenX:触摸目标在屏幕中的x坐标。
screenY:触摸目标在屏幕中的y坐标。
target:触目的DOM节点目标。
bubbles(起泡事件的类型)
cancelable(是否用 preventDefault() 方法可以取消与事件关联的默认动作)

根据touch对象跟踪触摸具体位置,从而判断触摸交互或手势事件。
弹性滚动
当客户端的页面滚动到顶部或底部的时候,
滚动条会收缩并让我们多滑动一些距离。
通过缓冲反弹的效果,带给用户良好的体验。

移动web页面也是拥有这样的能力的,
但滚动有几种情况需要考虑:
body层滚动:(系统特殊化处理)

自带弹性滚动,
overflow:hidden失效,
GIF和定时器暂停。

局部滚动:

没有弹性滚动,没有滚动惯性,不流畅。

局部滚动开启弹性滚动:

body {
overflow: scroll;
-webkit-overflow-csrolling: touch;
}

注意Andriod不支持原生的弹性滚动!
但可以借助第三方库iScroll来实现。
下拉刷新
顶部下拉一小距离,页面弹性滚动向下。
上拉加载
使用scroll事件而不是touch事件(andriod有bug)

4.课程总结

1人推荐
随时随地看视频
慕课网APP