# 移动 web

webview:原生提供运行在应用程序的内核浏览器,内核是 webkit

# 像素

  1. DPI/PPI:像素密度,表示屏幕每英寸所包含的像素点数目,数值越高,说明屏幕能以更高密度显示图像。
    • 结论:屏幕尺寸固定时,当 PPI 越大,像素的实际大小就会越小,当 PPI 越小,像素实际大小就越大。
  2. 设备独立像素:保证图像内容在不同的 PPI 设备看上去大小应该差不多,在 IOS 设备上叫 PT,Android 设备上叫 DIP 或 DP。与设备无关的逻辑像素,代表可以通过程序控制使用的虚拟像素,是一个总体概念,包括了 CSS 像素。
    • dp 和 px 的比例关系:window.devicePixelRatio ~= 物理像素/设备独立像素
  3. 物理像素:指的是屏幕渲染图像的最小单位,属于屏幕的物理属性,不可人为进行改变,其值大小决定了屏幕渲染图像的品质。
    • 获取屏幕的物理像素尺寸
      • window.screen.width; window.screen.height;
  4. 设备像素比:dpr(device pixel ratio):设备像素比,设备像素/设备独立像素,代表设备独立像素到设备像素的转换关系,在 JS 中可以通过 window.devicePixelRatio 获取。
  5. CSS 像素(CSS Pixel):适用于 web 编程,指的是我们在样式代码中使用到的逻辑像素,是一个抽象概念,实际并不存在。

# 移动端的视口

layout viewport(布局视口)指的是我们可以进行网页布局区域的大小
    document.documentElement.clientWidth;
    document.documentElement.clientHeight;
idear viewport(理想视口) 设备屏幕区域
    新设备 / 老设备
    window.screen.width / window.devicePixelRatio;
    window.screen.height / window.devicePixelRatio;

# meta 标签

用 meta 标签把 viewport 的宽度设为 device-width,同时 initial-scale=1,user-scalable=0,就构建了一个标准的移动 web 页面。

<meta name="viewport" content="width=device-width, initial-scale=1.0,
    maximum-scale=1.0,minimum-scale=1.0, user-scalable=0">

width:宽度设置的是viewport宽度,可以设置device-width特殊值
initial-scale:页面的初始缩放比,大于0的数字
               即layout viewport/ideal viewport宽度,相当于设置两个视口宽度相等
maximum-scale:当前页面的最大缩放比,大于0的数字
minimum-scale:当前页面的初始的最小缩放比,大于0的数字
user-scalable:用户是否可以缩放,yes或no(1或0)

让部分国产浏览器默认采用高速模式渲染页面

<meta name="renderer" content="webkit">
  • device-width:当前设备宽度
  • width:当前视口(浏览器)的宽度
  • min-device-width:在移动端和期望值一样 device:设备,它是指当前设备的宽度。 当拖动来改变浏览器大小的时候,当前终端设备的宽度并不会变化,意味着媒体查询条件不会响应
  • min-width:在 pc 端和移动端能正常的响应,效果一致。它是指当前可视区域的宽度

# flexible.js 原理

根据 document.documentElement.clientWidth 动态修改 <html>的 font-size ,页面其他元素使用 rem 作为长度单位进行布局,从而实现页面的等比缩放。

# 布局单位

px:像素
em:参考物是父元素的font-size,浏览器默认字体大小是16px
rem:参考物是相对于html根元素
vm:相对于视口的宽度,视口被均分为100单位,1vw等于视口宽度的1%
vh:相对于视口的高度,1vh等于视口高度的1%

# 1px 问题

1px 变粗的原因: 因为 css 中的 1px 并不等于移动设备的 1px,这些由于不同的手机有不同的像素密度。在 window 对象中有一个 devicePixelRatio 属性,它可以反应 css 中的像素与设备的像素比。在 retina 屏的 iphone 手机上,这个值为 2 或 3, css 里写的 1px 长度映射到物理像素上就有 2px 或 3px 那么长。

解决方案:

1.viewport + rem

2.transform: scale(0.5)

3.媒体查询 + transfrom

# 常用设置

# meta 标签

<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"
/>
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- 添加到主屏后的标题(iOS 6 新增),是否启用 WebApp 全屏模式,删除苹果默认的工具栏和菜单栏 -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- 设置苹果工具栏颜色 -->
<meta name="format-detection" content="telephone=no" />
<!-- uc强制竖屏 -->
<meta name="screen-orientation" content="portrait" />
<!--  UC强制全屏 -->
<meta name="full-screen" content="yes" />
<!-- QQ强制全屏 -->
<meta name="x5-fullscreen" content="true" />

# 判断手机机型是否为 iphonex

;(function () {
  var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream
  var ratio = window.devicePixelRatio || 1
  var screen = {
    width: window.screen.width * ratio,
    height: window.screen.height * ratio
  }
  if (iOS && screen.width == 1125 && screen.height === 2436) {
    alert('iPhoneX Detected!')
  }
})()

# 怎么为 ios 平台和 android 平台分别定制样式

body 元素上默认会添加一个表示平台的 className(ios 或 android),可使用这个分别为 ios 和 android 定制样式

// 设置平台
;(function () {
  var isIos = navigator.userAgent.indexOf('iPhone') > -1
  var isAndroid = navigator.userAgent.indexOf('Android') > -1
  var platform = isIos ? 'ios' : isAndroid ? 'android' : ''
  if (isIos || isAndroid) {
    document.body.classList.add(platform)
    window.__platform__ = platform
  }
})()

# fastclick 原理

原理: 在检测到 touchend 事件的时候,会通过 DOM 自定义事件立即触发模拟一个 click 事件,并把浏览器在 300ms 之后真正的 click 事件阻止掉。