移动端内容简介

编写移动端页面与编写电脑版网页的方式有一些不同,本文将移动端页面的内容进行了总结,主要包括三个视口、物理像素与像素比、移动端事件等内容。

学习移动端过程中做的两个项目:音悦台 和 懒加载相册
GitHub地址:https://github.com/huajianduzhuo/mobile-project

像素

屏幕相关概念

屏幕尺寸

指屏幕的对角线的长度,单位是英寸,1英寸=2.54厘米。

常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0等。

屏幕分辨率

指在横纵向上的像素点数,单位是px,1px=1个像素点。
一般以 纵向像素 * 横向像素 来表示一个手机的分辨率。如 iphone6 的分辨率是 750*1334。(这里的1像素指的是物理设备的1个像素点)

屏幕像素密度/像素密度/屏幕密度

屏幕上每英寸可以显示的像素点的数量,单位是ppi,即“pixels per inch”的缩写。

屏幕像素密度与屏幕尺寸和屏幕分辨率有关

像素

移动端中的像素具有几种不同的概念,如物理像素、CSS像素、设备独立像素。

物理像素/设备像素

  手机分辨率(n x m)指的是手机横纵向上的像素点数,一个点(小方格)为一个物理像素,它是屏幕能显示的最小粒度。
  设备像素也被称为物理像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。
  任何设备的物理像素的数量都是固定的。

CSS像素

  CSS像素是一个抽象的单位,主要使用在浏览器上,用来精确的度量(确定)Web页面上的内容。它是为web开发者创造的,在css或者javascript中使用的一个抽象的层。
  一般情况下,CSS像素被称为与设备无关的像素(device-independent像素),简称为“DIPs”。
  在一个标准的显示密度下(普通屏),一个CSS像素对应着一个设备像素。

作为开发者,我们使用的每一个css和javascript定义的像素本质上代表的都是css像素,我们在开发过程中,并不在意一个css像素到底跨越了多少个设备像素。我们将这个依赖于屏幕特性和用户缩放程度的复杂计算交给了浏览器。

css像素与物理像素的关系

  定义一个 width 为 200px 的元素,它占据了200个 css像素,但200个 css像素占据多少个物理像素取决于屏幕的特性(是否是高密度,即像素比)和用户的缩放行为。
  在 iPhone6 的视网膜屏幕上,视网膜的像素密度是普通屏幕的两倍,这个元素就跨越了400个物理像素。如果用户放大,它将跨越更多的物理像素。

设备独立像素

  设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。

位图像素

  一个位图的像素是栅格图像(如:png, jpg, gif等)最小的数据单元。1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示。

像素比

设备物理像素和设备独立像素的比例。

window.devicePixelRatio = 物理像素 / 设备独立像素

视口

布局视口

布局视口(layout viewport)是指用于 CSS 布局的一块区域。

在 PC 端,横向布局默认是根据初始包含块决定,如设置一个块级元素的宽度为 20%,则该元素的宽度为初始包含块的宽度的 20%。在移动端,由布局视口代替初始包含块的作用。

  布局视口的概念,在极大程度上帮助了桌面网站到移动设备上的转移。大部分手机浏览器的默认布局视口大小为 980px,默认情况下,布局视口占满手机浏览器屏幕,除非页面中有块级元素的宽度大于这个值,则该元素的宽度会占满屏幕,而布局视口的宽度则会小于屏幕的宽度(此处所说的宽度均指css像素宽度,物理像素由手机品牌决定,不会改变)。

  可以通过 document.documentElement.clientWidth 来获取布局视口的大小。

视觉视口

  视觉视口(visual viewport)与设备屏幕一样宽,并且它的 css 像素的数量会随用户的缩放而改变。
  visual viewport的宽度可以通过 window.innerWidth 来获取,但在Android 2, Oprea mini 和 UC 8中无法正确获取。

布局视口限制了页面css布局,视觉视口会决定用户能看到的区域。

理想视口

  大多数移动设备浏览器的布局视口的默认宽度为 980px,且默认情况下,这 980px 像素的大小会占满整个屏幕,这样会导致 CSS 像素和物理像素的大小差异过大,将PC端页面转移到移动端后,页面元素显示过小,需要用户手动缩放来调节,而这是我们不想看到的。
  为了实现用户进入页面时,不需要缩放屏幕,就可以正常浏览页面,我们需要为移动设备专门开发网站。
  由于布局视口的默认宽度主要是为了能够容纳PC端的网页设置的,对于专门为移动设备开发的网页,这个宽度并不是一个理想的宽度,所以一些浏览器厂商引入了理想视口。
  理想视口是指页面的布局视口宽度与设备独立像素的值相等。

实现理想视口的代码:

<meta name="viewport" content="width=device-width" />

缩放

  缩放是指放大或缩小页面的行为。本质上讲,缩放是放大或缩小 1css 像素的大小的过程,当 css 像素与物理像素的大小比例改变时,用户看到的元素大小也会改变,但是元素css布局大小的值没变。
  用户进行缩放操作时,布局视口的宽度不会改变,但是由于 css 像素的大小发生改变,会导致视觉视口所包含的 css 像素个数改变,所以缩放会改变视觉视口的尺寸。

meta标签

<meta name="viewport" content="" />

移动端页面需要添加 name 属性为 viewport 的标签,该标签 content 属性内容如下

content属性

content 属性的值可以包含如下内容:

  • width [pixel_value | device-width] width
    – 直接去设置具体数值大部分的安卓手机是不支持的 但是IOS支持
  • initial-scale 初始缩放比例
  • user-scalable 是否允许缩放 (no||yes),默认允许
  • minimum-scale 允许缩放的最小比例
  • maximum-scale 允许缩放的最大比例
  • target-densitydpi
    – dpi_value 70–400 //每英寸像素点的个数
    – device-dpi 设备默认像素密度2
    – high-dpi 高像素密度
    – medium-dpi 中等像素密度
    – low-dpi 低像素密度
    – webkit内核不再支持了
  • height

示例:

1
2
<meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,
initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,target-densitydpi=device-dpi" />

width

width 用来设置布局视口的大小。上面介绍过的理想视口,设置 width=device-width,会使布局视口的大小变成理想视口的大小(即独立设备像素代表的值)。

旋转(横竖屏切换):
当用户旋转设备时,布局视口的宽度通常会发生改变。因为横竖屏时的理想视口尺寸不一样。但ios的safari很例外,基于性能的考虑它的布局视口不会做出改变。

initial-scale

设置缩放,缩放根据理想视口的大小为基础来计算。设置 inital-scale=1 其实等同于只设置 width=device-width。

通过 initial-scale 设置的缩放,与用户的缩放行为不同。用户的缩放行为不会改变布局视口的大小,只改变视觉视口的大小。而通过 initial-scale 设置的缩放,会使布局视口的大小跟随着视觉视口一起改变。

minimum-scale和maximum-scale

  • minimum-scale 允许缩放的最小比例
  • maximum-scale 允许缩放的最大比例

不设置这两个值时,页面默认缩放比例范围为20%-500%,设置最大和最小比例后,页面可缩放比例能够扩大到10%-1000%。

安卓的 webkit 内核不支持这两个属性,默认缩放范围为25%-400%。
ie内核同样不支持。

完美视口

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

  当 meta 标签中只设置 width=device-width 和 initial-scale=1.0 中的一个时,如果页面中存在过大的元素,有些浏览器会扩展布局视口的宽度来容纳这个元素。但是如果这两个属性都设置了,大部分浏览器则不会改变布局视口的大小。

布局视口在 width 和 initial-scale 产生分歧时,会选择两个中布局视口较大的那一个。

事件

基础事件

  • touchstart
    手指触摸。相当于PC端页面的 mousedown 事件
  • touchmove
    手指移动。相当于PC端页面的 mousemove 事件
  • touchend
    手指移动。相当于PC端页面的 mouseup 事件

事件目标元素

  在PC端页面中,事件处理函数的第一个参数 event 就是事件对象,可以直接通过 event 对象获取事件的一些信息。在移动端页面中,同样可以使用 event 对象,但是由于在移动端,可能不止有一个手指事件,所以仅仅通过 event 对象,无法获取所有的事件信息。
  event 对象提供了三个数组类型的属性,用于存储移动端的事件对象。

  • changedTouches
    目标元素上触发了目标事件的手指事件对象列表
  • targetTouches
    目标元素上的所有手指事件对象列表
  • touches
    手机屏幕上的手指事件对象列表

多指事件

多指事件

  • gesturestart
    手指触碰当前元素,屏幕上有两个或者两个以上的手指
    注意:我们说的多指,指定是两个手指
  • gesturechange
    手指触碰当前元素,屏幕上有两个或者两个以上的手指位置在发生移动
  • gestureend
    在 gesturestart 后, 屏幕上只剩下两根以下(不包括两根)的手指

以上三个事件只有iPhone 6 以上才能用。

旋转(rotation)

可以通过 event.rotation 属性获取多指事件时,目标元素上的手指旋转角度。一般只考虑0-90°。

缩放(scale)

可以通过 event.scale 属性获取多指事件时,目标元素上的手指缩放比例。

原声 JS 模拟多指事件

模拟 gesturestart

手指触碰当前元素,屏幕上有两个或两个以上手指

1
2
3
4
5
6
7
box.addEventListener('touchstart', function(event){
var touch = event.touches;
if(touch.length >= 2){
// 相应多指事件

}
});

将上面代码封装成函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function gesture(box, callback){

// 判断 gesturestart 的标识
var flag = false;

box.addEventListener('touchstart', function(event){
var touch = event.touches;
if(touch.length >= 2){
flag = true;
// 相应多指事件
if(callback && callback['start']){
callback['start']();
}
}
});

模拟 gesturechange

手指触碰当前元素,屏幕上有两个或两个以上手指位置在发生移动

1
2
3
4
5
6
7
8
9
box.addEventListener('touchmove', function(event){
var touch = event.touches;
if(touch.length >= 2){
// 相应多指事件
if(callback && callback['change']){
callback['change']();
}
}
});

模拟 gestureend

在 gesturestart 后,屏幕上只剩下两根以下(不包括两根)的手指

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    box.addEventListener('touchend', function(event){
var touch = event.touches;
if(touch.length < 2){
if(flag){
// 相应多指事件
if(callback && callback['end']){
callback['end']();
}
}
// 重置标识
flag = false;
}
});

} // 对应 gesture 函数开始
-------------本文结束感谢您的阅读-------------
Fork me on GitHub