详解小程序横屏方案对比


Posted in Javascript onJune 28, 2020

前言

随着小程序api开放的功能日渐增多,小程序可以做到的功能和展现形式也越来越多,其中横屏的展现形式就是其中的一种,而实现横屏的方案也有多种,但是每种方案都有一定的缺陷,恰巧最近也在横屏方案上踩了不少坑,接下来就来和大家分享一下小程序的不同横屏方案的优劣(踩坑心得)

组件自带横屏方法

小程序中的媒体组件一般都会提供全屏的方法,而且全屏方法中会提供一个direction的全屏参数,可以通过这全屏参数将小程序旋转90度横屏展示,这是小程序中最简单的横屏方法。

这个方法优点在于调用的组件全屏方法做的横屏,不需要考虑头部导航栏的胶囊按钮的显示问题,媒体组件在做全屏显示时,胶囊按钮会自动隐藏不见,同时大多数媒体组件都已经支持了同层渲染,可以通过z-index调整组件层级,因此用此法在横屏布局时可以在媒体组件上覆盖其他组件布局

缺点:这个方法的缺点也很明显,就是只能使用媒体相关组件才能有横屏的全屏,场景很单一,如果不是媒体组件或者不想全屏,那么对不起,此法不可用

计算加速度判断横屏

这个方法是之前有人发在微信社区里的一个方法,通过小程序提供的wx.onAccelerometerChange方法监听设备在x、y、z轴上的加速度,通过返回的重力加速度计算设备的旋转角度,下面贴出代码给大家参考:

// 0为竖屏,1为横屏
 let lastState = 0;
 let lastTime = Date.now();
 
 wx.startAccelerometer();
 
 wx.onAccelerometerChange((res) => {
  const now = Date.now();
   
  // 500ms检测一次
  if (now - lastTime < 500) {
   return;
  }
  lastTime = now;
 
  let nowState;
 
  // 57.3 = 180 / Math.PI
  const Roll = Math.atan2(-res.x, Math.sqrt(res.y * res.y + res.z * res.z)) * 57.3;
  const Pitch = Math.atan2(res.y, res.z) * 57.3;
 
  // console.log('Roll: ' + Roll, 'Pitch: ' + Pitch)
 
  // 横屏状态
  if (Roll > 50) {
   if ((Pitch > -180 && Pitch < -60) || (Pitch > 130)) {
    nowState = 1;
   }else {
    nowState = lastState;
   }
 
  }else if ((Roll > 0 && Roll < 30) || (Roll < 0 && Roll > -30)) {
   let absPitch = Math.abs(Pitch);
 
   // 如果手机平躺,保持原状态不变,40容错率
   if ((absPitch > 140 || absPitch < 40)) {
    nowState = lastState;
   }else if (Pitch < 0) {/*收集竖向正立的情况*/
    nowState = 0;
   }else {
    nowState = lastState;
   }
  }
  else {
   nowState = lastState;
  }
 
  // 状态变化时,触发
  if (nowState !== lastState) {
   lastState = nowState;
   if (nowState === 1) {
    console.log('change:横屏');
   }else {
    console.log('change:竖屏');
   }
  }
 });

更多的实现细节可以前往社区帖子查看,这个方法个人实际尝试过,确实可以判断设备处在横屏还是竖屏

优点:这个方法的优点在于可以监听到设备的横竖屏情况,然后根据项目需要展示不同横竖屏布局,自由度很高

缺点:这个方法的缺点在于在页面内容横屏时无法使头部导航栏的胶囊按钮横屏展示,因为头部导航栏的胶囊按钮始终是固定屏幕右上角不动的,这样会使得横屏效果有点奇怪,横屏是导航栏固定在左边是竖屏时的布局,除非横屏的布局是媒体组件的全屏,这样就能遮住胶囊按钮,自己自定义一个头部导航,这样就不会显得布局奇怪

pageOrientation

pageOrientation是小程序提供的配置属性,可以设置当前页面是横屏展示、竖屏展示、或者自动旋转,同时提供一个onResize的监听方法,当屏幕发生旋转时会触发onResize的回调,并且会在回调中返回当前是横屏还是竖屏以及相应区域的大小。

优点:配置即可,手机旋转触发监听事件,返回屏幕旋转后的宽高和当前横竖屏情况,横屏时胶囊按钮会自动旋转,这样页面布局就不会有上一个方法所提及的怪异布局

缺点:

  • 由于是配置形式,没办法主动调用,只能被动监听
  • 当用户将手机允许旋转关闭后,onResize的监听方法就不会触发
  • 由于小程序大多数时候使用的是rpx的单位,是一个基于响应区域大小的动态计算的单位,当屏幕发生旋转后,假设竖屏旋转到横屏,竖屏时响应区域为375 667,到了横屏时响应区域为667 375,此时onResize回调还没触发,此时的页面布局是竖屏的布局,但是由于响应区域发生变化375 667到667 375,rpx就会重新计算,此时页面的布局会突然变大,然后onResize回调触发后才会变为横屏布局,会有布局闪现错乱的情况
  • width:100%或者width:100vw这类的占满全部的样式也会出现问题,同样假设从竖屏切换到横屏,当竖屏切换的横屏时,此时width:100%的样式,计算100%的宽度还是竖屏时的375,不会立即切换到横屏时的667,因此切换到横屏时的一瞬间,能看到原来100%的样式,此时并没有占满100%,闪了一下375之后,然后才会占满,假设我们自定义的顶部标题栏,用了width:100%,那么我横屏时就会发现,标题栏宽度只有一半,然后才会占满

横屏时响应区域变化产生布局变化的解决办法

这个解决办法只能解决横屏时由于响应区域变化导致rpx重新的计算渲染的问题,既然rpx会在响应区域变化时重新计算渲染,那我们最直接粗暴简单的方法就是不使用动态计算的单位px,这样就不会在横屏时重新渲染计算,但是这样也有一个问题,就是在不同屏幕的大小的手机下也没法动态计算了

那有没有其他的更好办法呢?vmax、vmin这两个单位应该平时用的不多,个人也很少用,如果不是这次写小程序横屏,也不会关注到它

vmin:取值是当前vw和vh中较小的值,vmax:取值是当前vw和vh中较大的值

在竖屏时100vmin=375px,到了横屏时100vmin=375px,这样就能保证在横竖屏切换的时候内容大小不变,在小程序中使用calc(vmin/7.5),假设大小为10px,那么css为calc(10vmin/7.5),如果你嫌这么写麻烦,同时使用的是vs code,那么可以创建一个全局User Snippets:

"rpx to vmin" : {
 "prefix": "tovmin",
 "body": ["calc($0vmin / 7.5)"],
 "description": "rpx to vmin"
 }

这样在写css时直接写tomin就会将calc($0vmin / 7.5)输出

详解小程序横屏方案对比

官方snippets创建步骤

总结

小程序中的横屏方案总是有这样或者那样的问题,并没有完美的解决方案,有时还是小程序自身原因导致的,我们能做的只是寻找解决办法或者换个交互设计,这篇文章的目的就是希望对大家在做横屏方案时提供一点帮助,少踩坑,这是我的踩坑经历,提供给大家借鉴,同时也有我的一些解决办法,如果大家有更好的方案,可以一起学习。

到此这篇关于详解小程序横屏方案对比的文章就介绍到这了,更多相关小程序横屏内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
简明json介绍
Sep 28 Javascript
Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法
Aug 08 Javascript
原生JS操作网页给p元素添加onclick事件及表格隔行变色
Dec 01 Javascript
IE、FF浏览器下修改标签透明度
Jan 28 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
Aug 22 Javascript
jQuery实现鼠标滑过链接控制图片的滑动展开与隐藏效果
Oct 28 Javascript
Bootstrap Table 搜索框和查询功能
Nov 30 Javascript
VUE安装使用教程详解
Jun 03 Javascript
selenium+java中用js来完成日期的修改
Oct 31 Javascript
Vue实现页面添加水印功能
Nov 09 Javascript
使用PreloadJS加载图片资源的基础方法详解
Feb 03 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
Aug 13 Javascript
微信小程序实现上传多张图片、删除图片
Jul 29 #Javascript
js模拟实现百度搜索
Jun 28 #Javascript
微信小程序地图实现展示线路
Jul 29 #Javascript
vuex实现购物车的增加减少移除
Jun 28 #Javascript
JavaScript实现Tab标签页切换的最简便方式(4种)
Jun 28 #Javascript
vuex实现购物车功能
Jun 28 #Javascript
JavaScript图像放大镜效果实现方法详解
Jun 28 #Javascript
You might like
《破坏领主》销量已超100万 未来将继续开发新内容
2020/03/08 其他游戏
人大复印资料处理程序_输入篇
2006/10/09 PHP
Yii2 GridView实现列表页直接修改数据的方法
2016/05/16 PHP
PHP处理数组和XML之间的互相转换
2016/06/02 PHP
PHP生成图片验证码功能示例
2017/01/12 PHP
PHP编程获取图片的主色调的方法【基于Imagick扩展】
2017/08/02 PHP
PHP基于关联数组20行代码搞定约瑟夫问题示例
2017/11/07 PHP
php微信扫码支付 php公众号支付
2019/03/24 PHP
jquery操作select大全
2014/04/25 Javascript
javascript中innerText和innerHTML属性用法实例分析
2015/05/13 Javascript
JavaScript获取浏览器信息的方法
2015/11/20 Javascript
整理Javascript基础语法学习笔记
2015/11/29 Javascript
jQuery事件绑定on()与弹窗实现代码
2016/04/28 Javascript
vue.js指令v-for使用及索引获取
2016/11/03 Javascript
js获取隐藏元素的宽高
2017/02/24 Javascript
vue.js源代码core scedule.js学习笔记
2017/07/03 Javascript
JavaScript实现的斑马线表格效果【隔行变色】
2017/09/18 Javascript
electron-vue开发环境内存泄漏问题汇总
2019/10/10 Javascript
盘点提高 Python 代码效率的方法
2014/07/03 Python
Python随机生成均匀分布在单位圆内的点代码示例
2017/11/13 Python
使用Python批量修改文件名的代码实例
2019/01/24 Python
python实现两个经纬度点之间的距离和方位角的方法
2019/07/05 Python
python自定义函数实现最大值的输出方法
2019/07/09 Python
对Python生成器、装饰器、递归的使用详解
2019/07/19 Python
利用python对excel中一列的时间数据更改格式操作
2020/07/14 Python
Python 捕获代码中所有异常的方法
2020/08/03 Python
意大利独特而优质的家居用品:Fazzini
2018/12/05 全球购物
英国老牌潮鞋店:Offspring
2019/08/19 全球购物
企划主管岗位职责
2013/12/12 职场文书
物流管理专业推荐信
2014/09/06 职场文书
高中运动会广播稿
2014/09/16 职场文书
师德师风剖析材料
2014/09/30 职场文书
开除员工通知
2015/04/22 职场文书
2016年感恩母亲节活动总结
2016/04/01 职场文书
Python数据分析入门之教你怎么搭建环境
2021/05/13 Python
详解nginx安装过程并代理下载服务器文件
2022/02/12 Servers