移动端开发
学习内容
- 移动端开发相关基础知识
- 项目案例实战
学习目标
- 掌握移动端开发的相关概念和名词
- 设计稿静态化,并适配绝大多数的移动设备
移动端特点
移动端与 PC 端网页有所不同,有以下几个特点
- 小屏幕
- 触摸交互
- 屏幕尺寸繁多
相关概念
移动端开发包含一些概念和专有名词,面试题以及以后的工作沟通经常会用到。
屏幕相关
屏幕大小
屏幕大小指屏幕的对角线的长度,单位一般是英寸。常见的手机屏幕大小 3.5、4、4.7、5.0、5.5、6.0等。常见手机屏幕查看网址 http://screensiz.es/
注意:
英寸的英文为 inch , 英尺的英文是 foot 4.7inch
1foot = 12inch 1inch=2.54cm
屏幕分辨率
屏幕分辨率是指屏幕横纵向上的像素点数。一般表示形式 x * y 或者 y * x 表示。例如 IPhone 6 的屏幕分辨率为 750 * 1334,华为 P30 的分辨率为 2340 * 1080。
注意:
- 屏幕分辨率是一个固定值,生产出来就固定了,无论手机屏幕还是电脑屏幕。
- 屏幕分辨率与显示分辨率不同。计算机可以修改显示分辨率,信号传递给屏幕,屏幕会进行计算,在屏幕上显示。
- 1080P 的分辨率是1920x1080 720P 1280 * 720
- 2K 屏幕是单一方向分辨率具有约 2000 像素的显示设备。最标准的 2K 分辨率为 2048×1024
几款手机的分辨率
型号 | 分辨率 |
---|---|
IPhone 3GS | 320 * 480 |
IPhone 4 / 4s | 640 * 960 |
IPhone 5 / 5s | 640 * 1136 |
IPhone 6 / 7 / 8 | 750 * 1334 |
华为 P30 | 1080 * 2340 |
IPhone X | 1125 * 2436 |
像素相关
物理像素 / 设备像素
设备像素 / 物理像素是一个长度单位。 1 物理像素对应显示设备中一个微小的物理部件。
设备像素是手机屏幕的一个参数,由手机制造商决定。例如 IPhone 6 的物理像素为 750 * 1334
设备独立像素 / 设备无关像素
设备独立像素,简称 DIP(device-independent pixel),又称为设备无关像素,是一个长度计量单位。
设备独立像素也是手机屏幕的一个参数,由手机制造商决定。例如IPhone 6 的设备独立像素为 375 * 667
1 个设备独立像素可以认为是计算机坐标系统中的一个点,代表可以通过程序控制使用的虚拟像素。
- 普通屏幕下 1 设备独立像素 等于 1 物理像素
- 高清屏幕下 1 设备独立像素 等于 N 物理像素
Retina 屏幕
Retina 是苹果公司 2010 年推出的一种显示标准,是把更多的像素点压缩至一块屏幕里,从而达到更高的分辨率并提高屏幕显示的细腻程度。
设备独立像素的出现,使得即使在高分辨率的屏幕下,也可以正常尺寸的显示元素,代码不受到设备的影响。
几款手机的屏幕像素参数,点击这里查看更多
型号 | 设备像素总和 | 设备独立像素总和 |
---|---|---|
IPhone 3GS | 320 * 480 | 320 * 480 |
IPhone 4 / 4s | 640 * 960 | 320 * 480 |
IPhone 5 / 5s | 640 * 1136 | 320 * 568 |
IPhone 6 / 7 / 8 | 750 * 1334 | 375 * 667 |
HUAWEI P10 | 1080 x 1920 | 360 x 640 |
IPhone X | 1125 * 2436 | 375 * 812 |
CSS 像素 / 逻辑像素
CSS 像素是 CSS 语言中用来表示长度的一个单位,单位为 px。
- CSS 像素不能直接跟现实中的长度单位换算
- CSS 像素主要用在 CSS 与 JS 中控制元素的大小与位置
位图像素
位图和矢量图
- 位图图像亦称为点阵图像或栅格图像,是由单个的像素点组成的。放大后会失真。
- 矢量图,也称为面向对象的图像或绘图图像,在数学上定义为一系列由线连接的点。放大后不会失真。软件有Adobe Illustrator,Sketch
位图像素也是一个长度单位。位图像素是栅格图像(如:png,jpg,gif等)最小的数据单元。
1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示
像素之间的关系
- 页面不缩放的情况下,CSS 像素 == 独立设备像素 == 逻辑像素 == DIP == 位图像素
- 在一个标准的显示密度下(普通屏),一个 CSS 像素对应着一个设备像素,高清屏幕下一个 CSS 像素 等于 N 个物理像素
像素密度
屏幕上每英寸可以显示的像素点的数量,单位是 ppi (pixels per inch ),这里还有另一个单位 dpi(dots per inch),两个值的计算方式都一样,只是使用的场景不同。 PPI 主要用来衡量屏幕,DPI 用来衡量打印机,鼠标等设备。
苹果曾经给出个一个标准:手机屏幕达到 300PPI、平板屏幕达到 220PPI、笔记本电脑屏幕达到 200PPI 即可认为是 Retina 屏幕。
像素比 / N倍屏
像素比(DPR dpr): 单一方向上设备物理像素和设备独立像素的比例。
1 | window.devicePixelRatio |
像素比的作用
程序可以根据像素比来显示不同的图片,达到清晰显示网页的效果。
1 | @media screen and (-webkit-min-device-pixel-ratio: 2) { |
并不是所有的图片都这样处理,只需要处理那些页面布局需要的图片和图标即可
视口
PC 端
在 PC 端,视口指的是浏览器的可视区域。其宽度和浏览器窗口的宽度保持一致。在 CSS 标准文档中,视口也被称为初始包含块,它是所有 CSS 百分比宽度推算的根源。
移动端
移动端的视口与 PC 端不同,有三个视口
- 布局视口
- 视觉视口
- 理想视口
布局视口
布局视口是用来放置网页内容的区域。
一般移动设备的浏览器都默认定义一个虚拟的布局视口(layout viewport),用于解决早期的页面在手机上显示的问题。 视口大小由浏览器厂商决定,大多数设备的布局视口大小为 980px。
获取方式
1 | document.documentElement.clientWidth |
视觉视口
视觉视口就是用户可见的区域。
获取方式
1 | window.innerWidth |
注:不缩放的情况下,视觉视口宽度 == 布局视口宽度。
理想视口
宽度与屏幕同宽的布局视口称为理想视口。 理想视口的好处
- 用户不需要缩放和滚动条就能看到网站的全部内容。
- 针对移动端的设计稿更容易开发。
注意:理想视口不是真实存在的视口
设置理想视口的方法
1 | <meta name="viewport" content="width=device-width" /> |
缩放
PC 端
放大时
- 布局视口变小
- 视觉视口变小
- 元素的像素大小不变
缩小时
- 布局视口变大
- 视觉视口变大
- 元素的像素大小不变
移动端
放大时
- 布局视口不变
- 视觉视口变小
缩小时
- 布局视口不变
- 视觉视口变大
注意:移动端缩放不会影响页面布局
真机测试流程
真机测试是项目测试必需的一个流程,一定要掌握!!!
关闭防火墙
webstorm -> ctrl + alt + s -> 搜索 debugger -> 修改端口并选中两个多选框 端口要大于 1024 建议用 8000 8888
使 PC 与手机处于同一个网络。手机连接电脑 wifi,或者电脑连接手机热点,两者在同一个 wifi 下最方便。
cmd 查看电脑无线网卡的 IP(ipconfig)
webstorm 在浏览器中预览文件,将 localhost 更改为 IP
打开草料网址 https://cli.im/ 将 URL 转化为二维码,手机扫描即可 😎
viewport 控制
viewport 标签是苹果公司在 2007 年引进的,用于移动端布局视口的控制。
使用示例
1 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scaleable=no,maximum-scale=1.0, minimum-scale=1.0"> |
viewport 相关选项
- width 布局视口宽度
- initial-scale 初始化缩放比例
- minimum-scale 最小缩放比例
- maximum-scale 最大缩放比例
- user-scalable 设置是否允许用户缩放
- viewport-fit auto/contain/cover
width
width 值可以是数字,也可以是设备宽度表示 device-width,这样可以得到完美视口
initial-scale
initial-scale 为页面初始化时的显示比例。
scale = 屏幕宽度独立像素 / 布局视口宽度。 // iphone6 0.5
注意:
- chrome 测试该参数会有偏差,真机测试
- initial-scale = 1.0 也可以得到完美视口
- initial-scale 会影响布局视口和视觉视口的大小
- width 与 initial-scale 同时设置时,会选择尺寸较大的那个
minimum-scale
设置允许用户最小缩放比例。
minimum-scale = 屏幕独立像素宽度 / 视觉视口 //iphone 6 0.5
maximum-scale
设置允许用户最大缩放比例,苹果浏览器 safari 不认识该属性
maximum-scale = 屏幕独立像素宽度 / 视觉视口 // 2
user-scalable
是否允许用户通过手指缩放页面。苹果浏览器 safari 不认识该属性。
viewport-fit
设置为 cover 可以解决『刘海屏』的留白问题
移动端事件
事件类型
移动端事件列表
- touchstart 元素上触摸开始时触发
- touchmove 元素上触摸移动时触发
- touchend 手指从元素上离开时触发
- touchcancel 触摸被打断时触发
这几个事件最早出现于IOS safari中,为了向开发人员转达一些特殊的信息。
应用场景
touchstart 事件可用于元素触摸的交互,比如页面跳转,标签页切换
touchmove 事件可用于页面的滑动特效,网页游戏,画板
touchend 事件主要跟 touchmove 事件结合使用
touchcancel 使用率不高
注意:
- touchmove 事件触发后,即使手指离开了元素,touchmove 事件也会持续触发
- 触发 touchmove 与 touchend 事件,一定要先触发 touchstart
- 事件的作用在于实现移动端的界面交互
事件绑定
方式一
1 | box.ontouchstart = function(){ |
方式二
1 | box.addEventListener('touchstart', function(){ |
这里推荐使用第二种,第一种有时会失灵。
点击穿透
touch 事件结束后会默认触发元素的 click 事件,如没有设置完美视口,则事件触发的时间间隔为 350ms 左右,如设置完美视口则时间间隔为 5ms 左右。
如果 touch 事件隐藏了元素,则 click 动作将作用到新的元素上,触发新元素的 click 事件或页面跳转,此现象称为点击穿透
解决方法
阻止当前元素事件的默认行为。
1 | cls.addEventListener('touchstart', function(e){ |
阻止顶级元素事件的默认行为,可以增加一个包裹元素绑定,也可以给 document 和 window 绑定,不过需要关闭被动模式
1 | document.addEventListener('touchstart', function(e){ |
使用非链接的元素代替 a 标签,并绑定 touchstart 事件
1 | <div class="item"> |
延时隐藏遮盖元素
1 | setTimeout(function(){ |
页面跳转的选择
移动端页面跳转可以使用 a 链接,也可以使用 touchstart 事件来触发 JS 代码完成跳转
- 效率上,touchstart 速度更快
- SEO 优化上, a 链接效果更好
浏览器默认行为
这里指的浏览器默认行为主要有两个
- 滑动露白
- 页面缩放
为什么要阻止这些默认行为
这样可以让网页在不同的浏览器都有一样的表现。
如何阻止默认行为
可以给 document 绑定 touchstart 事件,并阻止默认行为,不过需要关闭被动模式。这里推荐创建一个包裹元素,绑定 touchstart 事件并阻止默认行为。
CSS 代码
1 | html, body, #app { |
HTML 代码
1 | <body> |
JS 代码
1 | app.addEventListener('touchstart', function(e){ |
后遗症
最外层元素阻止了 touchstart 默认行为之后,会产生一些意外现象😭
- 链接失效
- 内容无法选择
- form 元素无法获得焦点
灵丹妙药
产生『后遗症』的原因在于 touchstart 阻止了默认行为,后续所有的操作都已经失效。解决问题只需要给目标元素绑定 touchstart 事件并阻止事件冒泡,这样当前操作的默认行为仍然可用。
1 | var link = document.getElementsByTagName('a')[0]; |
注: 不是非要阻止浏览器的默认行为,这是一种极端要求的应对方法,正常只需要设置完美视口即可。
事件对象属性
touch 事件对象中有 3 个非常重要的属性
- changedTouches
- targetTouches
- touches
touchstart 事件
在 touchstart 事件中,
changedTouches 为当前在元素上同时按下的触点对象数组。
targetTouches 为按下后,当前元素上的触点对象数组
touches 为按下后,当前屏幕上所有的触点对象数组
touchmove 事件
在 touchmove 事件中
changedTouches 为当前在元素上同时滑动的触点对象数组。
targetTouches 为滑动时,当前元素上的触点对象数组
touches 为滑动时,当前屏幕上所有的触点对象数组
touchend 事件
在 touchend 事件中
changedTouches 为当前在元素上同时抬起的触点对象数组。
targetTouches 为结束时时,当前元素上的触点对象数组
touches 为结束时时,当前屏幕上所有的触点对象数组
触点对象
每一个触点对象都包含一些位置信息,其中包括
- clientX 相对可视区域左侧的偏移
- clientY 相对可视区域顶侧的偏移
- pageX 相对文档左侧的偏移
- pageY 相对文档顶部的偏移
小案例
- 触摸拖拽
- 竖向滑屏
- 画板
适配
移动端设备的屏幕尺寸繁多,要想让页面的呈现统一,需要对不同尺寸的设备进行适配。适配的方式主要有两种
- viewport 适配
- rem 适配
viewport 适配
拿到设计稿之后,设置布局视口宽度为设计稿宽度,然后量尺寸进行布局即可。
rem适配
em 和 rem
em 和 rem 都是 CSS 中的长度单位。而且两个都是相对长度单位,不过两个有点区别
- em 相对的是父级元素的字体大小
- rem 相对的是根元素的字体大小
核心是等比缩放
rem 适配的策略有以下几种
方法一
先按照 IPhone 6 进行页面布局,再进行适配
- 完美视口设置
- 设计稿总宽 375 布局
- 设置 font-size 100px 尺寸转为 rem
- 增加 JS 代码进行页面适配
方法二
编写时直接使用 rem 单位进行布局
- 完美视口设置
- 总宽 375 布局
- 以 font-size 100px 进行尺寸换算,设置 rem
- 增加 JS 代码进行页面适配
方法三
选择一个设计稿宽度的比例尺寸作为根元素的字体大小
- 完美视口设置
- 通过 JS 设置页面的根元素字体大小。可以除以 10 也可以除以其他的数字
- 根据设计稿使用 rem 设置元素大小
1px 边框问题
高清屏幕下 1px 对应更多的物理像素,所以 1 像素边框看起来比较粗,解决方法如下
方法一
- 边框使用伪类选择器,或者单独的元素实现。例如底部边框
1 | .box2::after{ |
- 在高清屏幕下设置
1 | @media screen and (-webkit-min-device-pixel-ratio: 2){ |
方法二
- rem 页面布局
1 | var fontSize = 50; |
元素的边框设置为 1px
通过 viewport 中的 initial-scale 将页面整体缩小
1 | var dpr = window.devicePixelRatio; |
- 重新设置根元素字体
1 | document.documentElement.style.fontSize = fontSize * dpr + 'px'; |
附录
chrome 插件安装
- 下载 crx 插件文件,如 caoliao.crx
- 更名为 .rar 后缀, 例 caoliao.rar
- 解压文件,得到 caoliao 文件夹
- chrome 浏览器 -> 右上角 ┆ -> 更多工具 -> 扩展程序 -> 右上角开启开发者模式 -> 左侧已解压的扩展程序 -> 选择 caoliao 文件夹 👌