viewport
layout viewport(布局视口)
一般移动设备的浏览器都默认设置了一个viewport 元标签,定义一个虚拟的layout viewport(布局视口),用于解决早期的页面在手机上显示的问题。iOS, Android基本都将这个视口分辨率设置为 980px,所以pc上的网页基本能在手机上呈现,只不过元素看上去很小,一般默认可以通过手动缩放网页。
visual viewport(视觉视口)和物理像素
visual viewport(视觉视口)备物理屏幕的可视区域,屏幕显示器的物理像素,同样尺寸的屏幕,像素密度大的设备,硬件像素会更多。
ideal viewport(理想视口)和 dpi (设备逻辑像素)
ideal viewport(理想视口)通常是我们说的屏幕分辨率。
dip (设备逻辑像素)跟设备的硬件像素无关的。一个 dip 在任意像素密度的设备屏幕上都占据相同的空间。
逻辑像素宽度x倍率 = 物理像素宽度
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
属性名 | 取值 | 描述 |
---|---|---|
width | 正整数 或 device-width | 定义视口的宽度,单位为像素 |
height | 正整数 或 device-height | 定义视口的高度,单位为像素,一般不用 |
initial-scale | [0.0-10.0] | 定义初始缩放值 |
minimum-scale | [0.0-10.0] | 定义缩小最小比例,它必须小于或等于maximum-scale设置 |
maximum-scale | [0.0-10.0] | 定义放大最大比例,它必须大于或等于minimum-scale设置 |
user-scalable | yes/no | 定义是否允许用户手动缩放页面,默认值yes |
width属性被用来控制layout viewport(布局视口)的宽度,layout viewport(布局视口)宽度默认值是设备厂家指定的。iOS, Android基本都将这个视口分辨率设置为 980px。我们可以 width=320 这样设为确切的像素数,也可以设为device-width这一特殊值,一般为了自适应布局,普遍的做法是将width设置为device-width
width=device-width 也就是将layout viewport(布局视口)的宽度设置 ideal viewport(理想视口)的宽度。网页缩放比例为100%时,一个CSS像素就对应一个 dpi(设备逻辑像素),而layout viewport(布局视口)的宽度,ideal viewport(理想视口)的宽度(通常说的分辨率),dpi的宽度值是相等的。
自适应font-size的设置
(function () {
window.addEventListener("orientation" in window ? "deviceorientation" : "resize", setSize);
setSize();
function setSize() {
var html = document.documentElement;
var hWidth = html.getBoundingClientRect().width;
html.style.fontSize = hWidth / 15 + "px";//根据不同的屏幕宽度重置html的字体大小//15为自定义比例
}
})()
获取设备逻辑像素,设置根元素font-size的大小为页面宽度/15,而rem是相对于根元素的font-size大小,也就是说1rem = 页面宽度/15,假设设计图宽度为750px,那么 1rem = 750/15 = 50px,假设设计图上一元素宽度为 25px,则 转换成rem为 25/50 = 0.5rem;在实际应用手机屏幕逻辑像素为320px,则1rem = 320/15 = 21.33px;则设计图25px宽度元素,在css中写为:width:.5rem,则实际显示尺寸为25/50*21.33 = 10.66px;
rem
rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。
移动端事件
在模拟器下用事件绑定的方式添加touch事件,时好时坏,但是在真机上没有问题,最好用事件监听添加事件
在移动端也支持mouse事件,但是mouse事件的执行,会有300ms左右的延迟
ontouchstart//手指触碰元素
ontouchmove//手指触碰元素之后在屏幕上滑动
ontouchend//手指触碰元素之后在屏幕上抬起
事件点透
手指按下之后,会先执行touch事件,然后记录点击的坐标,300ms之后,在该坐标上查找元素,如果元素上有鼠标事件就执行
解决办法:
preventDefault()//在webkit的模拟器下,目前已经不支持在document上阻止默认事件,真机没问题
移动端event属性
clientX/clientY //相对于屏幕左上角的坐标
pageX/pageY//相对于页面左上角的坐标
- ev.changedTouches[index]//手指操作的集合(触发当前事件的手指列表)
- ev.targetTouches 当前元素上的手指列表
- ev.touches 当前屏幕上的手指列表
index//第几根手指
function () {
var touchs = ev.changedTouches[0];
touchs.pageY;
}
阻止默认事件(preventDefault())可以解决以下问题
- 在iOS10之后,viewport中禁止用户缩放和最大缩放比例失效
- 鼠标事件,在移动端会有点透问题
- 在iOS下会有系统默认的回弹(橡皮筋问题)
阻止默认事件 带来的危害
- 阻止文字的选中
- 阻止所有的系统菜单
- 阻止页面默认的系统滚动条
- 阻止页面上所有的链接跳转
- 阻止页面上的表单控件获得焦点
不推荐的解决方案
- 给单个控件添加阻止冒泡
各种方案
- input可以在touchstart的时候 手动获得焦点
- 链接可以在JS中自己添加跳转
查询横竖屏
window.orientation//记录手机横竖屏状态
- undefind //设备不支持横竖屏切换
- 90 -90 //横屏
- 0 180 //竖屏
orientationchange//监测横竖屏切换
window.addEventListener(‘orientation’ in window ?'orientationchange':'resize',function(){
setSize();
//放置有部分手机带有动画,所以延迟在执行一次
setTimeout(function(){
setSize();
},500)
})
function setSize(){
var html = document.documentElement;
html.style.fontSize = html.clientWidth/16 + "px";
}
devicemotion//检测重力加速度
安卓和iOS下数值相反
window.addEventListener('devicemotion',function(e){
var motion = e.accelerationIncludingGravity;
montion.x//x方向加速度
montion.y//y方向加速度
montion.z//z方向加速度
})
deviceorientation//检测手机旋转角度变化
window.addEventListener('deviceorientation',function(e){
var motion = e.accelerationIncludingGravity;
e.beta//围绕x轴旋转(-180 - 180)
e.gama.y//围绕y轴旋转(-90 - 90)
e.alpha//围绕z轴旋转(0 - 360)
})
navigator.userAgent//判断是安卓还是iOS
function getIos(){
var u = navigator.userAgent;
//var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
return isiOS;
}