移动端开发的基本观点chrome
像素基础知识api
viewport原理解析布局
弹性布局学习
响应式设计测试
1rem的运用spa
移动端的事件scala
zepto库的使用设计
移动端开发的意义
移动端用户使用量 -> 市场需求 -> 市场供给 -> 公司须要移动端开发人才 -> 工资高,就业易 -> 涌现大波程序猿 -> 到了猴年马月,工资才会降下来 -> 新的技术涌现,VR/AI -> 市场需求攀升 -> 重走一波老路......code
扯远了,以上大体就是学习移动端开发的动机;事件
移动端开发的认识
移动端开发就是手机端开发吗?
No、No、No...
移动端是一个大的范畴,小羊认为应该包括智能手机、平板在内的移动设备,主要是这二者;
移动端开发入门的学习路径
目录就是
先抛3个概念,px(CSS pixels)
:虚拟像素,能够理解为“直觉”像素,我要这个元素宽高10px;dp(device pixels)
:设备像素(物理像素),能够理解为实际的像素,这个宽高为10px的元素在设备中实际用了多少个物理像素点表示;dpr(device pixels ratio)
:设备像素比,公式为1px = (dpr)^2 * 1dp
,能够理解为1px由多少个设备像素组成;
3个概念整合理解就是:
我为一个元素设置的宽高为10px,那么实际在显示设备中用多少个设备像素真实表示呢?dpr=2
的话,那么1px由4个设备像素显示,若是是10px,那么显示设备实际用40个dp去显示10px;dpr=1
,则1px由1个设备像素显示;
px和dp的区别就是直觉认为只有10px和真实使用40dp;
为何会出现dpr>=2的情形?dpr=1不是更加符合个人认知和理解吗?
还不是人们为了追求更高的分辨率所致,分辨率越高图像越清晰!!!;
可是Mac的Retina屏和通常PC的在相同尺寸下,图像却清晰许多,为肾?
dpr>=2
所致啊!!!
别的品牌机子老老实实1px = 1dp,Mac倒是1px = 4 dp,因此你直觉认为你们都使用一样多的像素点表示图像(这是没错滴),实际背后Mac用了多1倍(指的是dpr)的设备像素显示图像;
实际应用中,显示设备不会直接给你个px和dpr
你实际看到的是如下的参数,下面是肾6Plus的显示屏参数信息:
再抛几个概念,可别晕咯...
英寸:这里指的是屏幕主对角线的尺寸,1英寸=2.54cm,5.5英寸约等于14cm(13.97cm)
分辨率:1920*1080像素,这里指的是物理像素(设备像素)
ppi(pixels per inch):每英寸的像素点,这里肾6Plus为每英寸有401个像素点
那么ppi是如何计算出来的呢?
顾名思义,每英寸的像素点(设备像素),已知屏幕分辨率和主对角线的尺寸,则ppi等于
var 斜边尺寸 = V(1920^2+1080^2) V表明开根号 var ppi = 斜边尺寸/5.5 ppi = 401ppi
如今咱们知道,ppi越高,每英寸像素点越多,图像越清晰;
和先前的知识点有什么关系?
毕竟这些参数是外国人先发明的,他们会优先选择本身熟悉的计量单位做为显示设备的工厂标准参数,所以ppi就用做显示设备的工业标准;
告诉业界人士,ppi达到多少是高清屏,此时对应的dpr是多少,而不直接告诉你我如今的显示设备dpr是多少
毕竟人们直接听到像素分辨率会更加有反应
下面是不一样ppi对应的dpi:
ldpi | mdpi | hdpi | xhdpi | |
---|---|---|---|---|
ppi | 120 | 160 | 240 | 320 |
默认缩放比 | 0.75 | 1.0 | 1.5 | 2.0 |
【注】Retina屏都是dpr>=2的高清屏
肾6Plus的dpr为3,是超高清屏;
到目前为止,咱们了解到:
给你一个显示设备,设备分辨率为1920*1080,尺寸为5.5英寸,能够计算出其ppi = 401,根据ppi得知其dpr = 3,
由此能够该设备1px = (3^2)dp,其虚拟像素为1920/3 = 660px,1080/3 = 360px,即虚拟分辨率为360*660;
此时,若是你在代码设置元素的宽高为360*660到的话,会发现它的实际尺寸就等于肾6Plus的屏幕尺寸;
【ppi】
一个颇有意思的现象是,当你把上面的代码在chrome下使用设备模拟方式,模拟肾6Plus的时候,神奇的事情发生了,该元素设置的宽高明明就是手机的宽高,按常理应该占据整个屏幕,实际倒是:
到底是怎么一回事?,如何解决这一问题呢?
好吧,做为实用主义者的大家(不是我哟),先讲解决方案:
在meta标签有一个viewport的属性,能够为这个属性设置width;
肾6Plus默认的width是980px,因此元素宽是360px,实际显示的尺寸是360px*360/980=132.24px(不信能够本身测试一下哟);
如今只要将viewport的width设置为360px,那么元素就能够占满全屏了;
如今就要引入另外一个概念:viewport
viewport的原理在于:
先将页面渲染在一个width为显示设备默认尺寸的viewport上,如肾6Plus为980px;
而后将viewport等比例缩放至整个手机屏幕上;
例如上例中,元素宽高为360*600px,先将元素渲染在宽度为980px的viewport上,而后等比例缩放在整个手机屏幕上;
viewport就是链接手机屏幕和页面的中间层
为何要画蛇添足呢?
想象一下,若是没有中间层,直接将一个页面宽度为980px的直接缩放至320px,那么里面的DOM节点将会进行重绘,颇有可能致使排版错乱;
viewport的做用是将全部的DOM节点先绘在宽度为980px的viewport上,而后整个viewport统一缩放,这样就能保证排版的正确性;
关于viewport,涉及两个概念:
layout viewport:布局viewport,能够理解为放置页面的幕布
visual vewport:视窗viewport,能够理解为屏幕的视窗
好比:
肾6Plus的visual viewport的宽度为360px,layout viewport为980px;
360px是屏幕视窗的虚拟像素,980px是放置页面的像素;
回顾一下,前面元素出现的缩放现象:
根据肾6Plus的物理分辨率1920*1080
以及5.5英寸的屏幕,计算出ppi = 401-> dpr = 3 -> 虚拟分辨率为640*360px
;
画一个宽度为360px的元素,理应充满整个手机屏幕 ,可是因为viewport的做用 -> 360px的元素画在980px的layout viewport上,而后等比例缩放在360px的visual viewport上-> 最终你看到的就是,360px的元素没法填充整个屏幕;
先前的一个解决办法是,改变layout viewport,即<meta name="viewport" content="width=360">
,让整个layout viewport就是360px,那么元素将填充整个屏幕;
以上都是世界观,给人一些概念性的理解,没法实操,下面就是方法论
实际移动端开发,咱们只需关注layout viewport,知道每一个移动设备提供给咱们多大尺寸的幕布,可是移动设备型号那么多,不可能一个个手动设置width呀!!!
动态设置layout viewport
<meta name="viewport" content="width=device-width">
上面的设置表示让layout viewport老是等于设备宽度,即visual viewport;
【注】细心的童鞋可能会注意到,肾6Plus的虚拟分辨率为何不是640*360px
,具体解答能够参考知乎问答
获取visual viewport和layout viewport的api
window.innerWidth:表示窗口的宽度(包含滚动条),即visual vewport的宽度 document.body.clientWidth:表示body元素的宽度(不包括border),即layout viewport的宽度
移动端其余初始化设置
intial-scale:页面首次显示时,可视区域的缩放级别,取值1.0则页面按实际尺寸显示,无任何缩放; no-scalable:是否容许缩放
一个完整的viewport属性的设置为:
<meta name="viewport" content="width=device-width,initial-scale=1,no-scalable=no">
上述完整的意思是,layout viewport等于设备的宽度,首次显示页面时不进行缩放也不容许用户缩放;
一开始讲px/dp/dpr/ppi的意义在于铺垫背景知识
理解上述知识后,给你一个移动设备的物理分辨率,如iPhone6 Plus19201080以及尺寸5.5inches,能够计算出其ppi为401->dpr = 3,从而测算出手机的虚拟分辨率为640360px;
原则上,你开发一个640*360px的元素就能够填充整个手机屏幕,可是因为viewport机制做用,效果未达预期
由此引出viewport概念,viewport能够分为visual viewport(视窗尺寸)和layout viewport(放置页面的“幕布“),iPhone6 Plus默认值为980px;
经过meta标签的viewport属性,能够动态设置layout viewport,实战中只须要设置:
<meta name="viewport" content="width=device-width,initial-scale=1,no-scalable=no">
你还能够经过window.innerWidth和document.body.clientWidth(前提是不设置body的宽度)
分别获取visual viewport和layout viewport;