APP开发目前有三种趋势,一种是原生APP,一种是网页APP,还有一种是H5APP。css
移动web开发:html
因为是基于webview,因此能够跨平台,不管是android仍是ios,都能很好的呈现。webview能够理解为是咱们的移动web页面和咱们手机原生之间的一个中间桥梁。
复制代码
也被称为设备像素 (Device independent pixels),即设备在出厂的时候就已经固定了像素。vue
咱们来看一下 iPhone6 (左图) 与 iPhone6 plus (右图) 的官方显示屏的规格说明:react
iPhone6 是 1334px x 750px 的像素分辨率,意思是当手机竖放的时候,横向有 750 个物理像素,纵向有 1334 个物理像素。android
在 CSS 中也被称为 CSS 像素 (CSS pixels),是为 Web 开发者创造的,在 CSS 和 JavaScript 中使用的一个抽象的层,每个 CSS 声明和几乎全部的 Javascript 属性都使用 CSS 像素。ios
例如咱们平时使用 Chrome 的设备调试工具的时候,iPhone6 是高 667px,宽是 375px,与苹果官方的 1334px x 750px,长宽分别少了 2 倍,那么面积就少了 4 倍。这就是常常说的 Retina 屏幕用四个(物理)像素表示一个(逻辑)像素。css3
咱们看的屏幕都是由一个一个的像素点组成的,以前咱们一直说的分辨率都是指实际像素尺寸,好比: 1920 * 1080就是 1920个像素点 * 1080个像素点。每一个点发出不一样的光就构成了咱们所看的画面。git
而到了咱们的移动端就不同了,由于咱们的手机自己就那么宽,要放下一个较宽的页面,显然,这种上诉的像素排放就不合适了。github
因此咱们要引入一个概念了: 像素密度(PPI)
。web
PPI: 准确的说是每英寸的长度上排列的像素点数量。1英寸是一个固定长度,等于2.54厘米.意思是一英寸中有多少个物理像素。
咱们再来看上面的图,一样的物理大小,PPI越高,所占据的像素点就越多,越高PPI的屏幕,显示一个像素点的面积就越小,一张由4x4个像素点组成的图显示在PPI为64的屏幕上,那么换到256PPI的屏幕上显示则会缩小为原来大小的一半。
反过来,若是要在PPI为256的屏幕上显示效果与PPI为64的屏幕同样,那么得要把图片放大2倍。
所以配有高清屏幕的手机,厂商为了其设备的可用性,即图标和文字能够被正确识别和准确点击,就必须保证各种素材在其设备上的显示与标清设备同样,而这个解决方法就是把全部尺寸都放大若干倍。这个放大比例就叫做设备像素比。
所以高清设备上应该配有高清图片显示,否则图片在高清设备上放大后没有足够的像素显示其细节,那么这张图片就会变得看起来很模糊。
在DPR为1(一般咱们的PC),1px等于1个物理像素。DPR为2,1px等于2个物理像素。
总结:
1. 咱们在开发中通常尽量使用iphone 6s来看成测试页面
2. 设计师给咱们的图纸通常都是使用该机型的像素尺寸来做图的
3. 咱们的话通常仍是使用物理尺寸(设备尺寸)来直观感觉和设计页面
4. 因为iphone6s的缩放比例是2倍,所以咱们使用的css像素就能够是设计图纸像素的一半。
复制代码
在移动端打开一个页面,若是浏览器先会以正常的比例来渲染页面,而后再自动地设置一个比例来缩放页面,目的是为了让内容更好地展现出来,即页面内容恰好铺满整个手机屏幕,固然若是页面没有禁止掉用户缩放的话,你也能够用两个手指把页面缩放回原始的比例。这整个过程就是经过视口(viewport)来实现的,原始页面渲染好后经过视口缩放使得与系统宽度同样,从而能够完整地展现页面。
移动端有三种视口:
布局视口: layout viewport
可视视口: visual viewport
理想视口: ideal viewport
复制代码
由于移动端的屏幕尺寸都比较小,咱们的页面根本放不下,这就有了布局视口的概念了,布局视口是虚拟的,通常都比较大,用户能够经过移动页面,缩放来经过可视视口查看页面的所有内容。
这时候虽然咱们的页面被缩放,显示在了可视视口内了,可是咱们的页面过小,容易影响用户的操做。
这时候就提出了理想视口,最初是由苹果公司提出的。理念:让咱们的布局视窗,等于咱们的理想视窗。而后把咱们页面的元素正好放入到咱们的页面中,元素的大小符合大众的阅读。
实现理想视窗,一般是:
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
复制代码
具体可看个人另外一篇文章。 响应式设计之 —— 媒体查询
首先咱们须要设置视窗
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
复制代码
而后设置html根元素的字体大小。
html{font-size:13.33333333vw}
复制代码
写的width:1rem,heigth:1rem
的div
就是50px* 50px
(iphone6为2倍屏,即对应750px设计稿上的100px*100px) 怎么搞定的,1句代码就能实现,太神奇。
原理:
vw为屏幕宽度的1/100。咱们的设计稿是750px的。那么100/750 = 0.1333333,那么1px就是0.1333333vw。100px就是13.333333vw了。这样咱们就能愉快的写rem了。当咱们html设置13.33333333vw的时候,咱们的1rem 就等于设计稿的100px,就等于咱们css像素的50px了。
此方案只能兼容手机,甚至连ipad兼容都很差,固然,此处的兼容不是兼容问题,是效果问题,只要兼容vw的设备都能用这个方案,可是因为适配的根本是vw这个, 这个会随着设备的宽度愈来愈大,那么用rem作单位的元素也会愈来愈大,以致于若是这个在pc上,那么无法预览了,效果会不好,字太大了.这样咱们能够设置一下当屏幕过大的时候的状况,咱们能够加一句代码
@media (min-width: 560px) {
html {
font-size: 54px;
}
}
复制代码
/** * [ 移动端适配方案 ] * @params designWidth 设计稿的实际宽度值,须要根据实际设置 * @params maxWidth 制做稿的最大宽度值,须要根据实际设置 * 例如设计稿为750,最大宽度为750,则为(750,750) * 拿iphone6做为实验机: 像素宽度为 750像素 css宽度为375px 最终设置html:font-size:50px; 1rem = 50px; 375px = 7.5rem * 若是设计稿是750像素宽的,因为dpr = 2,因此逻辑像素宽度只有 375 ,那么设计图上的 100px 表明 1rem; */
;
(function(designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement, // html节点
remStyle = document.createElement("style"),
tid;
// 计算 rem 比例
function refreshRem() {
// getBoundingClientRect 获取某个元素相对于视窗的位置集合
var width = docEl.getBoundingClientRect().width; // 获取整个文档元素的宽度,iphone6 是 375
maxWidth = maxWidth || 540;
width > maxWidth && (width = maxWidth); // 若是整个视窗的宽度大于 设计稿的最大宽度,那么就设置宽度为设计稿的最大宽度,
var rem = ( width / designWidth ) * 100; // 不一样的手机,width不同,计算 width / designWidth 为不一样的比例,好比 iphone6 下 rem = 50px iphone5 下 rem = 42.66666666666667px;
// 利用该效果来实现屏幕小就缩小,屏幕变大就适当的放大
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
// 将 style 标签引入
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle); // 头部head中插入
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
// 要等 wiewport 设置好后才能执行 refreshRem,否则 refreshRem 会执行2次;
refreshRem();
// 手机屏幕尺寸变化
win.addEventListener("resize", function() {
clearTimeout(tid); //防止执行两次
tid = setTimeout(refreshRem, 300);
}, false);
// 页面返回自动刷新
win.addEventListener("pageshow", function(e) {
if (e.persisted) { // 浏览器后退的时候从新计算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
// 文档所有资源加载完成
// 为body设置默认字体大小为16ox
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function(e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(750, 750);
复制代码
使用方法:
1.复制上面这段代码到你的页面的头部的script标签的最前面。
2.根据设计稿大小,调整里面的最后两个参数值。
3.(这里假设你的设计稿是750像素)使用1rem=100px
转换你的设计稿的像素,例如设计稿上某个块是100px*300px
,换算成rem则为1rem*3rem
。
demo:
// demo.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<!--必需要设置该项-->
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<title></title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="box">
我是盒子
</div>
<div class="test">
我是盒子
</div>
<script src="./flexible.me.js"></script>
</body>
</html>
复制代码
既然rem是根据html字体大小来定,咱们咱们彻底也能够经过css3媒体查询来完成这部分工做。
@media screen and (min-width:320px) {
html {
font-size: 21.33px
}
body {
font-size: 12px
}
}
@media screen and (min-width:360px) {
html {
font-size: 24px
}
body {
font-size: 12px
}
}
@media screen and (min-width:375px) {
html {
font-size: 25px
}
body {
font-size: 12px
}
}
@media screen and (min-width:384px) {
html {
font-size: 25.6px
}
body {
font-size: 14px
}
}
@media screen and (min-width:400px) {
html {
font-size: 26.67px
}
body {
font-size: 14px
}
}
@media screen and (min-width:414px) {
html {
font-size: 27.6px
}
body {
font-size: 14px
}
}
@media screen and (min-width:424px) {
html {
font-size: 28.27px
}
body {
font-size: 14px
}
}
@media screen and (min-width:480px) {
html {
font-size: 32px
}
body {
font-size: 15.36px
}
}
@media screen and (min-width:540px) {
html {
font-size: 36px
}
body {
font-size: 17.28px
}
}
@media screen and (min-width:720px) {
html {
font-size: 48px
}
body {
font-size: 23.04px
}
}
@media screen and (min-width:750px) {
html {
font-size: 50px
}
body {
font-size: 24px
}
}
复制代码
像苏宁易购等网站就是这么作的:
经过JavaScript读取屏幕宽度,而后根据宽度计算出对应的尺寸并设置根元素的font-size
。
咱们以320px
的屏幕基准像素为12px
为准则。
let htmlwidth = document.documentElement.clientWidth || document.body.clientWidth ; // 获取文档宽度
let htmlDom = document.getElementsByTagName('html')[0]; // 获取htmldom
// 若是页面宽度太大了的话,保持750
if(htmlwidth>750){ htmlwidth = 750}
// 320px的屏幕基准像素为12px
htmlDom.style.fontSize= 12 * (htmlwidth / 320) + "px";
复制代码
使用JS来获取屏幕宽度的好处在于能够100%适配全部的机型宽度,由于其元素的基准尺寸是直接算出来的。既然是JS代码,为了不形成由于动态设置元素的font-size而形成页面抖动,通常这部分代码咱们放在header底部去加载,并内联到html文档里面。
touchstart 手指接触屏幕时触发
touchend 手指离开屏幕时触发
touchmove 已经接触屏幕的手指开始移动的时候触发
touchcancel 某种touch事件非正常结束时触发
复制代码
有三个TouchList
,一个TouchList
表明一个触摸平面上全部触点的列表。
touches
targetTouches
changedTouches
复制代码
touches
列出全部当前在与触摸表面接触的 Touch 对象
targetTouches
包含全部仍与触摸平面接触而且touchstart事件与当前事件在同一个目标元素上发生的Touch对象。
changedTouches
用于记录想要改变最开始接触摸平面的触摸对象的touch对象。
经过上图咱们分析如下:
当只有一个元素的时候,三个touchList都是相同的。
当咱们的目标是div2,一次上来三次触摸分别为1,2,3。这时候touches记录所有的触摸点,targetTouches,记录所在目标上的全部触摸点,changedTouches记录第一个触摸点以后的触摸点。
复制代码
使用touch事件能够实现多种效果,好比拖拽,多点触摸,旋转手势等。
clientX:65 // 触摸点在浏览器窗口中的横坐标
clientY:18 // 触摸点在浏览器窗口中的纵坐标
force:1 // 触摸点压力大小
identifier:0 // 触摸点惟一标识(ID)
pageX:65 // 触摸点在页面中的横坐标
pageY:18 // 触摸点在页面中的纵坐标
radiusX:11.5 // 触摸点椭圆的水平半径
radiusY:11.5 // 触摸点椭圆的垂直半径
rotationAngle:0 // 旋转角度
screenX:560 // 触摸点在屏幕中的横坐标
screenY:175 // 触摸点在屏幕中的纵坐标
复制代码
最初的苹果公司为了让用户能够在手机上能够看咱们的页面,容许用户双击去放大效果,当用户触摸第一次以后,会在300ms以内去监听是否有下一次的触摸,用来判断是双击操做仍是单击操做,这就是300ms延迟的由来。
解决办法有:vue
的fastclick
和react
的react-tap
这两种。
点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件蒙层关闭按钮绑定的是touch事件,而按钮下边元素绑定的是click事件,touch事件触发以后,蒙层消失了,300ms后这个点的click事件fire,event的target天然就是按钮下面的元素,由于按钮跟蒙层一块儿消息了。
解决办法就是touch和click事件最好不要混用。