大家做项目的时候有没有遇到过一些不符合常理的开发需求,例如:开发的时候PC端和H5是两套站点,一般H5站点会适配平板设备,但是如果需要改成PC端适配平板呢;前期开发PC端没有考虑到PC端会有需要兼容平板的一天,完犊子了,这可怎么办?PC端的站点的长宽单位都是px,写的固定长度;而且会有固定的版型(就是页面一般会有一个最小宽度,比如1200px,1280px,1380px这些不等),如果要重写自适应,恐怕劳力费时还不讨好,当我拿到这个需求时,内心是崩溃的,后来思考了下,也有办法处理,但是会引发另外一些问题,下面我们慢慢展开。

  1. 这个项目PC的版型1380px,也就是小于这个宽度将以横向滚动条展示内容;首先看下面的viewport配置:
// nuxt.config.js
meta: [{ name: "viewport", content: "width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" }
]

上面这个配置会在HTML页面生成一个meta标签,等同于原生下面配置:

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

上面配置完了之后会禁止用户缩放页面,很奈斯。凡事有意外IOS系统高版本上不接受meta标签限制,那么就需要通过其他方式来禁用用户缩放,看下面一段脚本代码:

// methods: {}
// 阻止IOS手动缩放stopIOSScale() {// 阻止双击放大let lastTouchEnd = 0;document.addEventListener('touchstart', function(event) {if (event.touches.length > 1) {event.preventDefault();}});document.addEventListener('touchend', function(event) {let now = (new Date()).getTime();if (now - lastTouchEnd <= 300) {event.preventDefault();}lastTouchEnd = now;}, false);// 阻止双指放大document.addEventListener('gesturestart', function(event) {event.preventDefault();});}
  1. 前面第一步做完了,那么接下来就开始做页面的缩放程序处理了,比如有下一段渲染后的HTML代码:

    下面是进行处理PC端站点缩放的核心程序代码,在default模板里面处理的函数:
// default.vue
<template>
<div :id="test-id" :class="{ 'test-tablet': tablet.isTablet}">// ...to do
</div>
</template>
// ... to do
data() {return {tablet: {domHeight: 0, // 容器总高度isTablet: false, // 是否可旋转屏幕scaleRate: 1, // 缩放比例}}
}
mounted() {window.addEventListener('scroll', this.handleJsScroll); // 监听滚动事件做一些处理,如分屏加载,动态计算高度等this.orientationChange();
}
methods: {orientationChange() {try {let mql = window.matchMedia('(orientation: portrait)');this.handleOrientationChange(mql); // 第一次加载页面触发mql.addListener(this.handleOrientationChange); // 改变屏幕方向触发} catch (error) {console.log(error)}},handleOrientationChange(mql) {let screenWidth = 0, screenHeight = 0;// 苹果平板竖屏,(刷新和监听苹果屏幕旋转文档和屏幕宽度不一致)if (window.screen.width === document.documentElement.clientWidth) {screenWidth = window.screen.width || document.documentElement.clientWidth || document.body.clientWidth;} else {screenWidth = document.documentElement.clientWidth || window.screen.width || document.body.clientWidth;}// 苹果平板横屏,苹果屏幕旋转文档方向改变,屏幕方向不会改变,与安卓平板不一样if (window.screen.height === document.documentElement.clientWidth) {screenHeight = window.screen.height || document.documentElement.clientHeight || document.body.clientHeight;} else {screenHeight = document.documentElement.clientWidth || window.screen.height || document.body.clientHeight;}// 不是平板不处理if (!this.isTablet()) return;const isIPads = this.isIPad();const layoutEle = document.getElementById('__layout').style;this.tablet.isTablet  = true; // 根据是否是平板动态绑定样式处理一些特殊样式this.stopIOSScale();// 安卓和ios横屏和竖屏相反if(mql.matches) {let scaleRate = isIPads ? screenWidth : screenHeight;this.tablet.scaleRate = scaleRate / 1380;} else {let scaleRate = isIPads ? screenHeight : screenWidth;this.tablet.scaleRate = scaleRate / 1380;}// 缩放比例大于1说明可以完全展示不需要缩放,不处理if (this.tablet.scaleRate >= 1 || !screenWidth) return;layoutEle.minWidth = `${1380}px` // 给没有最小宽度的元素设置宽度,也可以通过上面设置的 .test-tablet .xxx {} 方式添加样式layoutEle.transform = `scale(${this.tablet.scaleRate})`layoutEle.transformOrigin = 'left top'},// 是否是苹果平板isIPad() {const ua = navigator?.userAgent;const isSafari = ua.includes("Safari") && !ua.includes("Linux");const isIphone = ua.includes("iPhone");const isIPad = isSafari && !isIphone && 'ontouchend' in document;return isIPad;},// 是否是安卓平板isPad () {const ua = navigator?.userAgent;const isPads = ua.includes("Safari") && ua.includes("Linux");const isPad = isPads && 'ontouchend' in document;return isPad;},// 是否是平板isTablet () {const isIPads = this.isIPad();const isPads = this.isPad();return (isIPads || isPads)},destroyed() {window.removeEventListener('scroll', this.handleJsScroll);}

注意到orientationChange函数此处监听的是媒体查询属性,另外有些其他资料写到用Window.orientation属性监听,但是这个属性已弃用了参考链接!

  1. 处理完上面这些基本上就差不多了,但是通过CSS缩放之后div还是会占用原有的位置,会在页面底部展示一大片空白区域,那么需要在滚动的时候对缩放的id__layout的容器外层的容器设置高度处理;如下面所示:
// methods: {}
// throttle from'lodash';
handleJsScroll: throttle(function () {// 滚动时动态修改外层容器高度if (this.tablet.scaleRate < 1) {let designEle = document.getElementById('__layout的外层容器').style;this.tablet.domHeight = document.getElementById('__layout').clientHeight || 0;designEle.height = `${this.tablet.domHeight * this.tablet.scaleRate}px`;designEle.overflow = 'hidden';}
}, 3000),

这样处理完成之后,兼容上到达了80% ~ 90%,有一些弹窗会因为缩放的原因导致与W3CCSS属性规范相违背,导致缩放之后id__layout的容器内position: fixed;效果变成了position: absolute;,这对一些提示信息和确认操作的交互体验是致命的;只要将弹窗el-dialog标签加上 append-to-body 属性配置就行了,加塞到body下面不会受到id__layout的容器缩放的影响;

后续:

这里面的一些判断平板(安卓和IOS)的函数可能不一定十分准确,因为查了很多资料并没有一个十分准确的方法去识别平板设备,大家可以根据自己实际情况去修改判断平板等相关函数。用PC端站点去兼容平板设备的逻辑思想大概就是这样的。

Vue/Nuxt框架开发的PC端网站兼容平板设备的相关推荐

  1. PC端网站兼容meta设置

    <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Com ...

  2. 基于 Vue JS、Element UI、Nuxt JS的项目PC端前端手册

    基于 Vue JS.Element UI.Nuxt JS的项目PC端前端手册 前言:笔记写于2020年5月左右,刚开始做前端时整理的笔记 1.环境搭建 1.安装nodeJs ​ 官网下载地址:http ...

  3. 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-2.启动项目

    技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-2.启动项目 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和本地环境 技能学习:学习 ...

  4. 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-3.路由、模型与数据库操作

    技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-3.路由.模型与数据库操作 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和本地环境 ...

  5. 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-6.用户登录(二),token验证

    技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-6.用户登录(二),token验证 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和本 ...

  6. 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-4.跨域且传输数据,并优化后端接口

    技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-4.优化后端接口,前端使用axios实现接口功能 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站 ...

  7. 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和本地环境

    技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和本地环境 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和本地环境 技能学习 ...

  8. 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-8.使用mavoneditor(vue的markdown编辑器),并批量上传图片

    技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-8.使用mavoneditor(vue的markdown编辑器),并批量上传图片 技能学习:学习使用php(tp6框架) + ...

  9. 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-7.分类的模型关联和通用CRUD接口

    技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-7.分类的模型关联和通用CRUD接口 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和 ...

最新文章

  1. Leangoo团队敏捷开发实现过程
  2. 解决chrome和firefox flash不透明的方法
  3. springboot整合shiro地址栏JSESSIONID问题
  4. postgresql 高可用 etcd + patroni 之二 patroni
  5. python去重复功能_消除Python列表重复的几种方法,python,去,一些
  6. docker安装nginx,配置nginx,并成功访问
  7. 阿里巴巴Python工程师面试题之一:单引号,双引号,三引号的区别
  8. php能干哪些副业,做副业,在能干的基础上踏实肯干
  9. nginx 静态文件
  10. SAP License:SAP 期待CO新帐 VS FI新总帐
  11. vs python调试配置_想用Python编程却不知如何下手?一篇搞定编程准备工作
  12. Spring MVC+ Spring + Mybatis “三大框架”介绍
  13. 映射的网络驱动器怎么共享_如何在Windows上通过网络共享CD和DVD驱动器
  14. 计算机联锁工程设计论文PPT,车站计算机联锁工程设计(哈尔滨)
  15. DH算法(密钥交换算法)
  16. 12.UniT:Multimodal Multitask Learning with a Unified Transformer
  17. Linux内核同步原语之信号量(Semaphore)
  18. RemoteTestkit远程真机调试平台使用教程
  19. 云和恩墨荣获阿里云云合计划2021年度优秀伙伴技术先锋奖
  20. 如何正确使用关键路径图?

热门文章

  1. Kubernetes——问题与解决方案
  2. 网站 ddos 服务_如何为您的网站选择DDoS保护服务
  3. Windows环境下redis重启
  4. sql进阶:求某个日期的连续上涨天数
  5. 【USACO】2009 Open Ski Lessons 滑雪课程
  6. vue基础知识(day06)
  7. Httpd服务进阶知识-HTTP协议详解
  8. [Microsoft Office] Office 2019及Microsoft 365账户无法登录或白屏问题
  9. linux运行文件命令
  10. 全连接前馈神经网络DNN