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

14 篇文章 0 订阅
3 篇文章 0 订阅

大家做项目的时候有没有遇到过一些不符合常理的开发需求,例如:开发的时候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代码:
    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端站点去兼容平板设备的逻辑思想大概就是这样的。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Nuxt框架中进行PC端字体大小适配的方法有多种。以下是其中一种常用的方法: 1. 使用CSS的`rem`单位:`rem`单位是相对于根元素(html)的字体大小而言的。可以通过设置根元素的字体大小,从而实现整个页面的字体大小适配。具体步骤如下: a. 在根组件(通常是`layouts/default.vue`)中,添加一个`mounted`钩子函数。 b. 在钩子函数中,使用`window`对象的`addEventListener`方法监听`resize`事件。 c. 在事件回调函数中,获取页面的宽度,并根据设计稿的尺寸计算出相应的根元素字体大小。 d. 使用`document.documentElement.style.fontSize`来设置根元素的字体大小。 e. 将设计稿的尺寸与实际页面的字体大小进行比例计算,从而实现字体大小的适配。 例如,假设设计稿的宽度为1920px,设计稿中某个元素的字体大小为16px,实际页面的宽度为960px,那么我们可以将根元素的字体大小设置为8px(960 / 1920 * 16),从而实现字体大小的适配。 引用 2. 使用CSS的`@media`查询:通过使用`@media`查询,可以根据不同的屏幕尺寸设置不同的字体大小。具体步骤如下: a. 在CSS文件中,使用`@media`查询根据不同的屏幕尺寸设置不同的字体大小。 例如,假设设计稿中某个元素的字体大小为16px,在页面宽度小于等于768px时,将字体大小设置为12px;在页面宽度大于768px时,将字体大小设置为16px。 ```css /* 在小于等于768px的屏幕尺寸下,设置字体大小为12px */ @media (max-width: 768px) { .element { font-size: 12px; } } /* 在大于768px的屏幕尺寸下,设置字体大小为16px */ @media (min-width: 769px) { .element { font-size: 16px; } } ``` 引用 这是在Nuxt框架中进行PC端字体大小适配的两种常用方法之一。你可以根据你的需要选择适合的方法来实现字体大小的适配

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值