记一次前端技术分享(移动端相关概念讲解)

移动端开发中的相关概念讲解

1、移动端自适配方案

移动端如何根据不同手机尺寸进行页面的适配

rem 自适应和 vw 自适应

rem 自适配

定义:相对单位,相对于根元素 html 的 font-size 大小
rem 是相对于 html 标签的 font-size 所设定的相对大小的一个相对单位,比如 html 的 font-size 为 750px,则 1rem 在设备上表现为 750px

通用方案:阿里巴巴的 Flexible 方案,html 的 font-size 大小等于页面宽度 10%,相当于把页面等于 10 个 rem

简单方案:头部嵌入一段 script,根据页面宽度改变根元素 html 的 font-size 大小,页面元素的单位用 rem,相当于元素是相对于根元素的 font-size 大小进行自适应变化

;(function(doc, win) {
  var docEl = doc.documentElement,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
    recalc = function() {
      // viewport的宽度
      var clientWidth = docEl.clientWidth
      if (!clientWidth) return
      if (clientWidth >= 750) {
        docEl.style.fontSize = '75px'
      } else {
        docEl.style.fontSize = 75 * (clientWidth / 750) + 'px'
      }
    }
  if (!doc.addEventListener) return
  win.addEventListener(resizeEvt, recalc, false)
  doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window)
如何将设计师的设计稿单位 px 转成 rem

例如,设计稿宽度是 750px,当设备宽度为 750px 时,1 个 rem 就是 75px,一个页面的宽度也就是 10 个 rem,px 转 rem 公式为:宽度(px)/rem 基准值(75),若用 sass 语法,可以写个 function 进行 rem 转换,也可直接用 postcss 插件:px2rem 来转换

vw 自适配

定义:相对于 viewport 窗口的宽度的大小的 1/100
1vw 就代表 1%宽度的 viewport 的宽度,100vw 代表 1 个 viewport 的宽度

使用 vw 做 css 单位,可以不用动态计算 html 元素的 font-size 大小,页面能根据不同宽度手机做自适应

如何将设计师的设计稿单位 px 转成 vw

例如,设计稿宽度是 750px,当设备宽度为 750px 时,1 个 vw 就是 7.5px,一个页面宽度就是 100vw
同理,计算公式:宽度(px)/ vw基准值(7.5)
也可以用 postcss 插件(postcss-px-to-viewport)进行计算

vw 对于浏览器兼容性不是很好

vw 兼容方案:https://www.w3cplus.com/css/vw-for-layout.html

类似的相对单位

em:相对于父元素 font-size 的大小

vh: 相对于 viewport 视口的高度的大小的 1/100

vmin: 相对于 viewport 视口宽度或高度较小值的 1/100

vmax:相对于 viewport 视口宽度或高度较大值的 1/100

vmin 和 vmax 单位是相对于 viewport 视口宽度或高度较大或者较小值的 1/100,也就是说不论横屏或者视频,这两个单位的相对值始终不会变化
用处:当我们不希望横屏或竖屏改变元素的宽高时,可以用着两个单位

2、浏览器内核

webview 上不同系统的渲染引擎有什么区别?

主流:ios 使用的 webkit,安卓使用的 blink

大概在 05 年左右苹果开发了 webkit 浏览器内核,浏览器主流内核就是 webkit,后面安卓也采用 webkit 浏览器内核。由于 webkit 初始架构比较简单,apple 基于原本的 webkit 开发了 webkit2,google 则根据 webkit 内核移植出新的浏览器内核 blink(chrome 版本 28 及往后使用该内核),Opera 后期也追随 google 用上了 blink 渲染引擎

为什么会有浏览器前缀

由于不同的浏览器会使用不同的内核,最初不同的内核对 css3 样式的兼容性不一样,所以存在不同浏览器前缀

  • -moz- :Firefox,GEcko 引擎
  • -webkit-: Safari 和 Chrome,Webkit 引擎
  • -o- :Opera(早期),Presto 引擎,后改为 Webkit 引擎
  • -ms- :Internet Explorer,Trident 引擎

为兼容不同浏览器,使用autoprefixer插件,可自动添加浏览器前缀(ios8 出现 flex 布局不支持)

"browserslist": [
  "> 1%",
  "last 2 versions",
  "Android >= 3.2",
  "Firefox >= 20",
  "iOS 7"
]

webkit 内核大致结构:


webkit
  • 操作系统:是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行。WebKit 也是在操作系统上工作的。
  • 第三方库,为了 WebKit 提供支持,如图形库、网络库、视频库等。
  • WebCore 是各个浏览器使用的共享部分,包括 HTML 解析器、CSS 解析器、DOM 和 SVG 等。JavaScriptCore 是 WebKit 的默认引擎,在谷歌系列产品中被替换为 V8 引擎。
  • WebKit Ports 是 WebKit 中的非共享部分,由于平台差异、第三方库和需求的不同等原因,不同的移植导致了 WebKit 不同版本行为不一致,它是不同浏览器性能和功能差异的关键部分。
  • WebKit 嵌入式编程接口,供浏览器调用,与移植密切相关,不同的移植有不同的接口规范。

相关链接:

v8 引擎介绍:https://blog.csdn.net/swimming_in_it_/article/details/78869549

webkit 内核介绍:https://blog.csdn.net/offbye/article/details/40039289

3、viewport 的概念

viewport: 手机端浏览器的可视窗口大小,用来控制根元素容器的宽高,也就是整个浏览器的宽高,不能够被 css 修改,相当于 html 的一个父元素

相关概念:移动设备有三个 viewport,布局窗口、视觉窗口、理想窗口

布局窗口:可供页面布局的大小


布局窗口和视觉窗口

视觉窗口:在手机端上展示的大小

理想窗口:就等于设备屏幕的大小,也就是视觉窗口的大小

移动端开发常用 meta 标签来初始化 viewport 的缩放比,让布局窗口和视觉窗口保持一致

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

相关链接:http://www.w3cplus.com/css/viewports.html

4、iphone 的 retina 屏上 1px 问题

  • 物理像素:设备的像素,代表显示器的最小物理显示单元

  • 设备独立像素:可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如:css 像素)

  • dpr(device independent pixels): 物理像素/设备独立像素,可通过window.devicePixelRatio获取对应设备的 dpr

  • 比如 iphone6 的 dpr 是 2,它的设备宽度一般是 375px,但是实际物理像素是 750px,这个时候,如果一个 1px 的 border,显示在 iphone6 上其实是两个物理像素,所以会出现 1px 在 iPhone 上感觉会比较粗

解决方法:
直接针对 dpr 来设置,1/dpr 个像素,比如 dpr 为 2 则设置为 0.5px,或新增一个 1px 宽度的伪类,使用 transform 属性缩小到 0.5 倍宽度
直接将 meta 头标签,设置初始宽度为 1/dpr 倍物理像素,比如 dpr 为 2,则设置为:

<meta name="viewport" content="initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5, user-scalable=no">

此时页面相当于缩放到了原来 0.5 倍,但是 rem 是相对单位,所有页面布局和样式会整体自适应,同时此刻 1px 也对应 1 个物理像素

关于背景图或者相关的 icon,设计师一般也会提供 2 倍图甚至是 3 倍图,也是这个原因,可根据媒体查询到对应 dpr 是选择几倍图

相关文章:https://www.cnblogs.com/surfaces/p/5158582.html

5、媒体查询

目的:据页面的特定宽度来定义特殊的 CSS 规则(这里的宽度也是视口宽度(viewport))

/*
标示:@media
关键字: not only
设备类型:all、print、screen、speech
打印机:print
电脑或手机显示器:screen
阅读器: speech
且: and
或: ,
*/

/* 页面最大宽度为400px */
@media all and (max-width: 400px) {
  div {
    width: 300px;
  }
}

/* 指定显示器类型,页面最大宽度为400px且最小宽度为200px */
@media only screen and (max-width: 400px) and (min-width: 200px) {
  div {
    width: 300px;
  }
}

/* 排除显示器类型,页面最大宽度为400px且最小宽度为200px,或者dpr为2 */
@media not screen and (max-width: 400px) and (min-width: 200px),
  (-webkit-device-pixel-ratio: 2) {
  div {
    width: 300px;
  }
}

6、通过 js 获取相关的宽高属性

  • 屏幕尺寸:screen.width/height
    它们是显示器的宽高,不会随着浏览器宽高的变化而变化,通常除了数据统计,对我们没有任何意义

    屏幕尺寸
  • 页面尺寸:window.innerWidth/innterHeight
    浏览器的内部尺寸。它定义了当前用户有多大区域,可供你的 CSS 布局占用。你可以通过 window.innerWidthwindow.innerHeight 来获取,通常浏览器宽度方法或者缩小,会对应跟着方法或者缩小。

    页面尺寸
  • viewport 的尺寸:document.documentElement.clientWidth/clientHeight
    一般情况下,document.documentElement 是代表的 html 元素,但是 viewport 是比 html 更高级的元素,并且 html 的尺寸变化不会影响到 document.documentElement. clientWidth/clientHeight 的变化,所以实际上 document.documentElement.clientWidth/clientHeight 代表的是 viewport 的尺寸
  • document.documentElement.clientWidth/clientHeightwindow.innerWidth/innerHeight 的差别
    严格来说,两者基本一致,但是 window.innerWidth/innerHeight 实际上会包含滚动条的宽度,但是 document.documentElement.clientWidth/clientHeight 则不会

    viewport 尺寸
  • html 元素的尺寸:document.documentElement.offsetWidth/Height
    如果 clientWidth/Height 一直用以标示 viewport 的尺寸,我们该如何去获取<html>元素的尺寸呢?— document.documentElement.offsetWidth/Height,一般获取元素的大小也使用 offsetWidth/offsetHeight,会包含 border,padding
  • 获取元素相对于 viewport 的位置:getBoundingClientRect
    用法:var rect = element.getBoundingClientRect()
    返回值类型:TextRectangle 对象,每个矩形具有四个整数性质( 上, 右 , 下,和左 )表示的坐标的矩形,以像素为单位

7、iphonx 适配

设备安全区域

由于 iPhone X 的顶部和底部状态栏,以及全面屏的普及,会导致全屏的页面,四个圆角以及底部、顶部被遮住,因此需要根据 iPhone X 做一些适配
iOS 11 为屏幕适配引入了一个十分重要的概念:Safe Area

适配方案:
1、将 viewport-fit 通过 meta 标签设置为 cover,表示页面内容填充屏幕

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

2、使用 css 的 constant()函数做适配
如果页面只是简单的流式布局
ios11 之前使用的是 constant 做适配,ios11 之后使用标准的 env 做适配

body {
  padding-top: constant(safe-area-inset-top); //为导航栏+状态栏的高度 88px
  padding-left: constant(safe-area-inset-left); //如果未竖屏时为0
  padding-right: constant(safe-area-inset-right); //如果未竖屏时为0
  padding-bottom: constant(safe-area-inset-bottom); //为底下圆弧的高度 34px
  padding-top: env(safe-area-inset-top); //为导航栏+状态栏的高度 88px
  padding-left: env(safe-area-inset-left); //如果未竖屏时为0
  padding-right: env(safe-area-inset-right); //如果未竖屏时为0
  padding-bottom: env(safe-area-inset-bottom); //为底下圆弧的高度 34px
}

3、针对特殊情况单独处理

/*iPhoneX 的适配*/
@media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) {
  .iphonex-padding-bottom {
    padding-bottom: constant(safe-area-inset-bottom) !important;
    padding-bottom: env(safe-area-inset-bottom) !important;
  }
}

参考文档:https://www.cnblogs.com/lolDragon/p/7795174.html

8、使用 vue 的 异步组件处理加载状态

为减少手机端的首屏渲染时间,一般使用 vue-router 懒加载方案,但页面跳转首次访问会有卡顿现象

可在页面跳转中间加一层 loading 组件,此时可以使用 vue 的异步组件方案来处理

文档地址:https://cn.vuejs.org/v2/guide/components-dynamic-async.html#%E5%A4%84%E7%90%86%E5%8A%A0%E8%BD%BD%E7%8A%B6%E6%80%81

// route.js
import loadable from 'loadable.js'
const routes = [
  {
    path: '/loan-home',
    name: 'LoanHome',
    component: loadable(() => import('@/pages/xxx'))
  }
]

// loadable
export default asyncComponent => {
  const component = () => ({
    component: asyncComponent(),
    loading: LoadingComponent,
    delay: 0
  })
  return {
    render(h) {
      return h(component, {})
    }
  }
}

参考文档

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • 刚开始做移动端web开发的同学应该都碰到过页面适配问题,为什么我在开发手机上调试好的页面在其他手机会有这样或那样的...
    留七七阅读 19,285评论 5 80
  • 移动端开发 我们现在关注的点还在移动M站上,或者我们可以叫做webapp,其实就是运行在移动端浏览器中的web网站...
    WEB攻程狮阅读 656评论 0 0
  • 1.移动端迷之视口 为什么我称他为“迷之视口”,因为其实我听过很多人的分享,来讲解移动端视口的问题,但我好像都...
    buershero阅读 1,206评论 0 2
  • 那天登录好久没上的蚂蜂窝,整理之前的一些游记,翻到一条很有意思的评论:相比起其他方式,一个人旅行带给你的是怎样一种...
    肥熊胖猫阅读 758评论 0 4
  • 如叶,如风,似柔,似静,愿你我安稳如初,看花开落,看云卷舒,品人百态……
    歌云阅读 217评论 0 0