曾几何时,前端还仅仅是PC端的。随着移动时代的兴起,h5及css3的推陈出新。前端的领域慢慢的由传统的pc端转入了移动端,这也导致了前端这一职业在风口的一段时间出尽了风头。

从开始的惶恐和无从下手,慢慢的到了有了统一的技术方案去落地实现。

从手写不同尺寸的媒体查询css到以手淘的flexible.js来进行移动端的适配,虽然过程曲折,不过效果也是十分的显著,因为有了成熟的体系以后。什么东西就有据可寻,适配也就没那么困难了。

但是,因为这次引入了高德地图,所以在适配上出现了一点意料之外的问题。

首先,我要说下视口这个东西,因为手淘的这个方案是严重依赖视口这个概念的。

1.视口

1.1视口的分类

ppk将视口分为三大类:布局视口,可视视口,理想视口

那视口是什么呢?通俗点说就是就是浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域,但viewport又不局限于浏览器可视区域的大小,它可能比浏览器的可视区域要大,因为为了正常的显示PC端的网页,浏览器会将自己的layout viewport设置为一个较大的值,结果就是会出现左右的滚动条。当然viewport(visual viewport)也可能比浏览器的可视区域要小,比如有的手机自带的浏览器会有一个自带的黑色小边距。

布局视口和可视视口我们作基本了解即可。在实际工作中,我们需要接触和处理的更多是ideal viewport。

而我们前端一直孜孜以求的移动端的适配。其实就是为了让用户的浏览器中呈现的是我们的理想视口

ideal viewport并没有一个固定的尺寸,不同的设备拥有有不同的ideal viewport。

早期移动端开发,对于终端设备适配问题只属于Android系列,有320pt的,有360pt的,有384pt的等等。但随着iPhone6,iPhone6+的出现,从此终端适配问题不再是Android系列了,也从这个时候让移动端适配全面进入到“杂屏”时代。有320pt的,有375pt(iphone x)的,有414pt(plus)的等等。

http://viewportsizes.com里面收集了众多设备的理想宽度。

1.2 如何影响视口?

既然viewport这么重要,那我们怎么去控制他为我所用呢?这个时候,就轮到meta标签出场了。

先来一段我们在开发的时候最常用的一句话。

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

用下面的表格来解释一下content里面的属性

width 设置layout viewport  的宽度,为一个正整数,或字符串"width-device"
 height  设置layout viewport  的高度,这个属性对我们并不重要,几乎不使用
 initial-scale  设置页面的初始缩放值,相对于ideal viewport进行缩放,为一个数字,可以带小数
 minimum-scale  允许用户的最小缩放值,为一个数字,可以带小数
 maximum-scale  允许用户的最大缩放值,为一个数字,可以带小数
 user-scalable  是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许
<meta name="viewport" content="width=device-width">

width=device-width,通过这个特殊值。我们将layout viewport => ideal viewport

<meta name="viewport" content="initial-scale=1.0">

通过设置初始的缩放比率,我们也可以将layout viewport => ideal viewport

所以上面两种方式是殊途同归的。那么,为什么我们还要将两个都写上去呢?

答案:initial-scale=1.0是为了处理在 iphone、ipad上,无论是竖屏还是横屏,宽度都是竖屏时ideal viewport的宽度,

   width=device-width是为了处理在windows phone 上的IE 无论是竖屏还是横屏都把宽度设为竖屏时ideal viewport的宽度

<meta name="viewport" content="width=400, initial-scale=1.0">

如果出现了上面的这种怎么办呢?

这个时候浏览器会取它们两个中较大的那个值。例如,当width=400,ideal viewport的宽度为320时,取的是400;当width=400, ideal viewport的宽度为480时,取的是ideal viewport的宽度。

总结起来就是“谁大谁先行“

2.引入高德后页面的表现

在vue的spa项目中引入高德以后,我们发现在不同的dpr下,地图的显示效果差距非常大。

在dpr=3的时候,也就是plus的机型上,地图显得格外的小。几乎用肉眼是无法看清上面的字体。所以,这样说来,基于flexible的适配方法肯定是有问题的了。

而出现这个问题的原因就是我们的viewport被缩放了。

if (!dpr && !scale) {var isAndroid = win.navigator.appVersion.match(/android/gi);var isIPhone = win.navigator.appVersion.match(/iphone/gi);var devicePixelRatio = win.devicePixelRatio;if (isIPhone) {// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {dpr = 3;} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){dpr = 2;} else {dpr = 1;}} else {// 其他设备下,仍旧使用1倍的方案dpr = 1;}scale = 1 / dpr;}

通过上面的代码计算出了viewport缩放的比率。当处于iphone 6+plus的时候,scale = 0.333333333333....

metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

最后写到页面上面的结果就是:

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

所以,iphone plus是414pt,通过flexible将viewport缩小了0.33333333333,我们将414/0.3333333333=1242.0000001242

而正好高德地图通过canvas绘制的画布的宽度也就是1242。

3.如何解决这个问题

通过我的总结,处理这个问题的方法大致有三种

3.1 通过vue-router的路由守卫进行处理

beforeMount() {this.$nextTick(() = >{const dpr = document.documentElement.getAttribute('data-dpr')         if (dpr > 1) {window.tempViewport = document.querySelector('meta[name="viewport"]').getAttribute('content');        document.querySelector('meta[name="viewport"]').setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no');             window.tempDpr = dpr;        document.documentElement.setAttribute('data-dpr', 1);}})
},
beforeRouteLeave(to, from, next) {if (window.tempViewport) {document.querySelector('meta[name="viewport"]').setAttribute('content', window.tempViewport);         delete window.tempViewport;}if (window.tempDpr) {document.documentElement.setAttribute('data-dpr', window.tempDpr); 

        delete window.tempDpr;}next()
},

不过这样的方式不是很好,因为页面在过渡的时候会出现一瞬间样式的变形。而且如果在当前有地图的页面有其他结构的话,其他结构也会错乱。

Tips:如果不是SPA的应用,而且整屏页面是地图占满的情况下,这个方案还是可行的。

3.2 通过css scale属性

这个方法在我试验了以后,也存在问题。虽然地图的大小是正常了,但是在地图上进行点标记的时候,会出现地图位置的偏移。

Tips:如果仅仅是展示,而并没有任何交互的情况下,这个方式也是可行的。

3.3 通过设置dpr = 1 (推荐)

通过设置dpr=1,强制flexible布局对viewport不进行缩放。

<meta name="flexible" content="initial-dpr=1" />

这样,最后写到页面上的meta标签就是这样的。

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

既然viewport没有缩放了。高德地图通过canvas绘制的地图也就是按照我们的ideal viewport来进行处理了。

不过这种方式会产生另外两个副作用:

  • 通过缩放来处理的"1px问题"这里需要重新去处理了
  • 通过dpr设置的不同dpr下的文本字号大小,可能会出现13px这样很奇葩的尺寸了

第一个是适配中一个很经典的问题,我会放到随后去讲。而第二个问题只能暂时这样去处理了。

4.结尾

大漠对于这个问题的解释是:flexible已经完成自己的使命,该功成身退了。他推荐使用vw,vh标准的新布局方式。

而到底用不用这套方案,作为前端的我们也是见仁见智了!

转载于:https://www.cnblogs.com/ChengWuyi/p/8196647.html

从flexible.js引入高德地图谈起的移动端适配相关推荐

  1. three.js和高德地图结合引入obj格式模型-效果演示

    代码要放在web服务中去访问,three.js只有在服务中才能获取模型的材质图片!! 源代码地址: three.js和高德地图结合引入obj格式模型.zip-Javascript文档类资源-CSDN下 ...

  2. 【vue3引入高德地图】

    vue3引入高德地图 文章目录 vue3引入高德地图 前言 一.准备工作 1.开发文档 2.添加应用 二.使用步骤 1.npm 安装 2.地图容器创建 3.组件引入 4.js api 安全密钥 5.初 ...

  3. vue 高德地图标记_vue-element-admin 引入高德地图并做海量点标记

    第一步: 首先在index.html入口文件中添加引入高德地图的js,并填写自己在官网申请的key.如果没有申请不填写也是可以的. plugin:项目中如果有需要引入插件则使用没有直接去掉就行. 第二 ...

  4. Vue 引入高德地图 vue-amap

    一.在高德开发平台,获取Key(已有可跳过): 高德开发者平台-链接地址 1.控制台--我的应用--创建应用--添加key 创建应用  新建应用 选择web端(JS平台) last:到这里的 key ...

  5. flutter引入高德地图_玩玩Flutter Web —— 实现高德地图插件

    Red Deer 1.啰嗦几句 去年写了一个功能简单的高德地图插件给flutter_deer使用,当时支持了Android与iOS两端.前一阵子有一个issue问是否会支持Flutter Web,当时 ...

  6. 企业微信公众号网页开发之引入高德地图API

    test.jsp 页面文件 WxController.java 后端Controller层代码 WxService.java 后端Service层代码 WxDao.java 后端Dao层代码 一.JS ...

  7. uniapp h5 引入高德地图

    因地图收费.uniapp h5 是腾讯地图,公司为了少交一份钱,就改为引入高德地图 我才用是模板引入js 首先在项目跟根目录添加index.html <!DOCTYPE html> < ...

  8. vue 引入高德地图

    index.html 引入高德地图 <script type="text/javascript" >AMapLoader.load({"key": ...

  9. vue中引入高德地图

    ❤️❤️❤️ Topology可视化绘图引擎 ❤️❤️❤️ 总的来说,vue组件中使用高德地图的方式有两种,一种是vue-amap :一套专门用于vue的高德地图插件:另外一种是原生的高德地图. 方式 ...

最新文章

  1. RPC-原理及RPC实例分析
  2. 下面不属于python第三方库的安装方法的是-python第三方库的pip安装方法
  3. 解决: IDEA 代码 commit 后,Local Changes 中代码依旧在,提交失败,报错:is out of date
  4. 杭州保俶塔实验机器人_【科教有闻】高照实验学校Pepper机器人课程亮相2020(杭州)国际数字教育大会“智能教育引领未来”论坛...
  5. go使用mongodb
  6. JAVA 设计模式 装饰者模式
  7. 删数问题 详解(C++)
  8. lcd1602显示自己的学号和姓名拼音的c语言程序,LCD1602显示字符.doc
  9. 草料二维码 批量生成二维码
  10. 希尔伯特变换(Hilbert Transform)简介及其物理意义
  11. macbook安装佳能C3020打印机驱动安装错误代码701
  12. MathPage.wll not found
  13. 应急响应之windows进程排查
  14. 天津科技大学计算机专业,天津科技大学计算机科学与信息工程学院介绍
  15. ArrayList类的详解
  16. Tensorflow 2.3 model.evaluate报错InvalidArgumentError: Incompatible shapes: [1,64] vs. [1,128]
  17. 网络设计部分知识点总结
  18. 外卖匹配系统_快餐外卖系统得需求分析
  19. 软件学报投稿的大致时间线分享
  20. Nginx 服务 (编译安装--访问控制--虚拟主机)详解

热门文章

  1. 构建车联网信息服务平台
  2. Android端+Java服务端+servlet+MySQL二手商城设计
  3. Matlab·学习 | (一)太阳系模型
  4. oracle餐饮管理,餐饮经营管理计划指标数据
  5. Android monkey使用简略
  6. Titanic(泰坦尼克号)
  7. Unity2D学习笔记-Tilemap
  8. 深入理解TCP三次握手
  9. VS2005在Win7上兼容性问题解决
  10. JMeter入门教程(2) --Jmeter的下载