屏幕概念
屏幕尺寸
对角线的长度 (厘米)
屏幕分辨率
横纵向上物理像素的个数(物理像素)
屏幕密度
每英寸上物理像素的个数
视口尺寸
代表的横纵向上css像素的个数(css像素)
4个像素
物理像素
-
分辨率,是屏幕呈像的最小单位
-
一个物理像素占据的实际屏幕尺寸在不同设备上是否一样?
答:不一样
-
设备出厂时,该款设备所包含的物理像素的点数和一个物理像素所占据的实际屏幕尺寸是不会变的
css像素
-
是web开发者使用的最小单位
-
一个css像素最终一定会转成物理像素去屏幕上呈像
一个css像素到底占据多少个物理像素和谁有关?
- 屏幕的特性
- 用户的缩放行为
物理像素与css像素比例是谁在维护?
- 视觉视口(1.决定用户能看到什么;2.包住整个布局视口)
- 物理像素:屏幕的分辨率
- css像素: 布局视口尺寸
维护规则是什么?
加name为viewport的meta标签:
像素比
没有加name为viewport的meta标签:
布局视口尺寸 / 屏幕的分辨率(css像素/物理像素)
用户缩放行为区别
-
不考虑用户缩放
-
没有viewport
-
这块屏幕横向上占据了多少个物理像素(横向分辨率)
-
这块屏幕横向上占据了多少个css像素 (视觉视口的横向尺寸)
-
-
有viewport
-
像素比
-
一个方向上所占据的物理像素的个数/一个方向上所占据的css像素的个数
-
-
-
考虑用户缩放
在屏幕的特性的基础上:
- 放大:视觉视口包含的css像素的个数变少,1个css像素占据更多的物理像素
- 缩小:视觉视口包含的css像素的个数变多,1个css像素占据更少的物理像素
设备独立像素
是设备对接css像素的接口,一旦css像素与独立像素挂上勾(width=device-width)此时像素比才能发挥真正的作用
位图像素
- 图片的最小单位
- 位图像素与物理像素一比一时,图片才能完美清晰的展示
四个像素之间的关系
物理像素和设备独立像素
像素比: 一个方向上占据一块屏幕所需要的物理像素的个数 /一个方向上占据一块屏幕所需要的设备独立像素的个数 ;
物理像素和位图像素
1:1的时候才能完美清晰的展示
物理像素和css像素
普通屏:1比1
高清屏:
-
加name为viewport的meta标签
像素比
-
没有加name为viewport的meta标签
布局视口尺寸 / 屏幕的分辨率
css像素和设备独立像素
- 没有加name为viewport的meta标签:没有关系
- 加name为viewport的meta标签:可以认为css像素就是设备独立像素
3个视口
布局视口
决定页面的布局(css像素)
layout viewport:
- 手机上,为了容纳为桌面浏览器设计的网站,默认的布局视口的宽度远大于屏幕的宽度
- 布局视口的出现,在极大程度上帮助了桌面网站到移动设备上的转移。
- 可以通过document.documentElement.clientWidth来获取
- 在pc端,单独一个width为20%的元素最终拿到的值要根据初始包含块的width来决定,因为我们横向的布局都是按初始包含块开始填的,在移动端一样,不过我们这个时候应该叫它布局视口。
视觉视口
决定用户能看到什么
- 一个css像素到底占据多少个物理像素和视觉视口有极大的关系
- 一个视觉视口的实际尺寸是确定的(屏幕尺寸)
- 一个视觉视口包含的物理像素的个数是确定的(分辨率)
- 一个视觉视口包含的css像素的个数是不确定的(用户的缩放行为有关)
visual viewport:
visual viewport的宽度可以通过window.innerWidth 来获取,但在Android 2, Oprea mini 和 UC 8中无法正确获取。
理想视口
设备独立像素所代表的值
我们分析知道:布局视口的默认宽度并不是一个理想的宽度,对于我们移动设备来说,最理想的情况是用户刚进入页面时不再需要缩放。这就是为什么苹果和其他效仿苹果的浏览器厂商会引进理想视口!
只有是专门为移动设备开发的网站,他才有理想视口这一说。而且只有当你在页面中加入viewport的meta标签,
理想视口才会生效。
<meta name="viewport" content="width=device-width" />
这一行代码告诉我们,布局视口的宽度应该与理想视口的宽度一致
2个操作
4.1 用户
只影响视觉视口
4.2 系统
影响布局视口和视觉视口
- 放大:
- 放大一个css像素的面积,视觉视口的尺寸变小,一个css像素包含的物理像素的个数变多
- 缩小:
- 缩小一个css像素的面积,视觉视口的尺寸变大,一个css像素包含的物理像素的个数变少
像素比
- 物理像素/设备独立像素
- 一个方向上所占据的物理像素的个数/一个方向上所占据的css像素的个数
3个意外
太大的元素
使用完美视口(有width=device-width和initial-scale=1.0)解决太大的元素超过视觉视口后不出滚动条的问题
width和initial-scale的冲突
谁大听谁的
等比问题
没有viewport
等比
页面展示太小,用户体验不好
有viewport
不等比
- 每一个css像素在不同设备占据的实际屏幕尺寸一样。
- 每一个css像素在不同设备占据的物理像素的个数不一样(像素比)
- 一个物理像素占据的实际屏幕尺寸在不同设备上是不一样的
适配方案
rem适配
(function(){
var styleNode = document.createElement("style");
var w = document.documentElement.clientWidth/16;
styleNode.innerHTML = "html{font-size:"+w+"px!important}";
document.head.appendChild(styleNode);
})()
原理
改变了一个元素在不同设备上占据的css像素的个数
rem适配的优缺点
- 优点:没有破坏完美视口
- 缺点:px值到rem的转换太复杂
viewport适配
(function(){
var targetW = 640;
var scale = document.documentElement.clientWidth/targetW;
var meta = document.querySelector("meta[name='viewport']");
meta.content="initial-scale="+scale+",minimum-scale="+scale+",maximum-scale="+scale+",user-scalable=no";
})()
原理
每一个元素在不同设备上占据的css像素的个数是一样的。但是css像素和物理像素的比例是不一样的
viewport适配的优缺点
- 优点:所量即所得
- 缺点:没有使用完美视口
一物理像素
rem+系统缩放
- 主体适配采用rem适配 并放大rem的基值(dpr倍)
- 再通过系统缩放 缩回dpr倍,initial-scale=1/dpr
(function(){
var dpr = window.devicePixelRatio||1;
var styleNode = document.createElement("style");
var w = document.documentElement.clientWidth*dpr/16;
styleNode.innerHTML="html{font-size:"+w+"px!important}";
document.head.appendChild(styleNode);
var scale = 1/dpr;
var meta = document.querySelector("meta[name='viewport']");
meta.content="width=device-width,initial-scale="+scale;
})()
响应式+变换缩放
@media only screen and (-webkit-device-pixel-ratio:2 ) {
#test{
transform: scaleY(.5);
}
}
@media only screen and (-webkit-device-pixel-ratio:3 ) {
#test{
transform: scaleY(.333333333333333333);
}
}
queryselector的坑
- queryselectorAll:静态列表
- queryselector:静态列表的第一个
全面禁止移动端触摸事件的默认行为
document.addEventListener("touchstart", function (ev) {
ev = ev || event;
ev.preventDefault();
}, { passive: false })
一个隐患
移动端页面上所有的滚动条失效
解决方案
- 在需要滚动的地方取消冒泡
方法1:event.cancelBubble=true
方法2:event.stopPropagation();
- 或者自定义更牛逼的滚动条!
事件点透
原理
- PC端的事件可以在移动端触发
- PC端事件有300毫秒延迟
- 移动端事件不会有延迟
event
- changedTouches:触发当前事件的手指列表
- targetTouches:触发当前事件后元素上的剩余手指列表
- touches:触发当前事件后屏幕上的剩余手指列表
Tween算法
var Tween = {
Linear: function(t,b,c,d){ return c*t/d + b; },
back: function(t,b,c,d,s){
if (s == undefined) s = 1.70158;
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
}
}
t:当前是哪一次
b:初始位置
c:最终位置与初始位置之间的差值
d:总次数