移动WEB的硬知识

1、概述

APP开发目前有三种趋势,一种是原生APP,一种是网页APP,还有一种是H5APP。css

移动web开发:html

  • 跑在咱们手机端的web页面,(H5页面)
  • 跨平台
  • 基于webview
  • 告别IE,拥抱webkit,兼容性问题不用担忧
  • 更高的适配性,和性能要求
因为是基于webview,因此能够跨平台,不管是android仍是ios,都能很好的呈现。webview能够理解为是咱们的移动web页面和咱们手机原生之间的一个中间桥梁。
复制代码

2、像素

一、物理像素

也被称为设备像素 (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

三、像素密度PPI

咱们看的屏幕都是由一个一个的像素点组成的,以前咱们一直说的分辨率都是指实际像素尺寸,好比: 1920 * 1080就是 1920个像素点 * 1080个像素点。每一个点发出不一样的光就构成了咱们所看的画面。git

而到了咱们的移动端就不同了,由于咱们的手机自己就那么宽,要放下一个较宽的页面,显然,这种上诉的像素排放就不合适了。github

因此咱们要引入一个概念了: 像素密度(PPI)web

PPI: 准确的说是每英寸的长度上排列的像素点数量。1英寸是一个固定长度,等于2.54厘米.意思是一英寸中有多少个物理像素。

四、设备像素比(DPR)

咱们再来看上面的图,一样的物理大小,PPI越高,所占据的像素点就越多,越高PPI的屏幕,显示一个像素点的面积就越小,一张由4x4个像素点组成的图显示在PPI为64的屏幕上,那么换到256PPI的屏幕上显示则会缩小为原来大小的一半。

反过来,若是要在PPI为256的屏幕上显示效果与PPI为64的屏幕同样,那么得要把图片放大2倍。

所以配有高清屏幕的手机,厂商为了其设备的可用性,即图标和文字能够被正确识别和准确点击,就必须保证各种素材在其设备上的显示与标清设备同样,而这个解决方法就是把全部尺寸都放大若干倍。这个放大比例就叫做设备像素比

所以高清设备上应该配有高清图片显示,否则图片在高清设备上放大后没有足够的像素显示其细节,那么这张图片就会变得看起来很模糊。

看上图,蓝色的为物理像素,绿色的为css像素。

在DPR为1(一般咱们的PC),1px等于1个物理像素。DPR为2,1px等于2个物理像素。

总结:

1. 咱们在开发中通常尽量使用iphone 6s来看成测试页面
2. 设计师给咱们的图纸通常都是使用该机型的像素尺寸来做图的
3. 咱们的话通常仍是使用物理尺寸(设备尺寸)来直观感觉和设计页面
4. 因为iphone6s的缩放比例是2倍,所以咱们使用的css像素就能够是设计图纸像素的一半。
复制代码

3、viewport 视口

在移动端打开一个页面,若是浏览器先会以正常的比例来渲染页面,而后再自动地设置一个比例来缩放页面,目的是为了让内容更好地展现出来,即页面内容恰好铺满整个手机屏幕,固然若是页面没有禁止掉用户缩放的话,你也能够用两个手指把页面缩放回原始的比例。这整个过程就是经过视口(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">
复制代码

4、flex弹性布局

5、媒体查询

具体可看个人另外一篇文章。 响应式设计之 —— 媒体查询

6、移动端适配

一、方案一:使用vm结合rem来实现适配

  • 前提: 咱们的设计稿是750px的。

首先咱们须要设置视窗

<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:1remdiv就是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;
  }
}
复制代码

二、方案二:Rem自适应js之精简版flexible.js

代码地址

/** * [ 移动端适配方案 ] * @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>

复制代码

三、方案三:媒体查询修改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
  }
}

复制代码

像苏宁易购等网站就是这么作的:

四、方案四:JS动态计算html字体大小

代码地址

经过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文档里面。

7、touch事件

一、事件类型

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事件能够实现多种效果,好比拖拽,多点触摸,旋转手势等。

touch手势实例

三、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以内去监听是否有下一次的触摸,用来判断是双击操做仍是单击操做,这就是300ms延迟的由来。

解决办法有:vuefastclickreactreact-tap这两种。

五、点击穿透

点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件蒙层关闭按钮绑定的是touch事件,而按钮下边元素绑定的是click事件,touch事件触发以后,蒙层消失了,300ms后这个点的click事件fire,event的target天然就是按钮下面的元素,由于按钮跟蒙层一块儿消息了。

解决办法就是touch和click事件最好不要混用。

相关文章
相关标签/搜索