详解小程序横屏方案对比


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 相关文章推荐
解决html按钮切换绑定不同函数后点击时执行多次函数问题
May 14 Javascript
jQuery实现简单网页遮罩层/弹出层效果兼容IE6、IE7
Jun 16 Javascript
JQuery中的事件及动画用法实例
Jan 26 Javascript
每天一篇javascript学习小结(Array数组)
Nov 11 Javascript
JS实现支持Ajax验证的表单插件
Mar 24 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
Jun 07 Javascript
Javascript必知必会(四)js类型转换
Jun 08 Javascript
JavaScript基于原型链的继承
Jun 22 Javascript
利用Vue.js实现求职在线之职位查询功能
Jul 03 Javascript
knockoutjs模板实现树形结构列表
Jul 31 Javascript
JS基于贪心算法解决背包问题示例
Nov 27 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
Sep 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
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
如何判断元素是否为HTMLElement元素
2013/12/06 Javascript
javascript复制粘贴与clipboardData的使用
2014/10/16 Javascript
使用正则表达式的格式化与高亮显示json字符串
2014/12/03 Javascript
js 左右悬浮对联广告特效代码
2014/12/12 Javascript
javascript+canvas实现刮刮卡抽奖效果
2015/07/29 Javascript
jquery插件pagination实现无刷新ajax分页
2015/09/30 Javascript
JavaScript encodeURI 和encodeURIComponent
2015/12/04 Javascript
js创建jsonArray传输至后台及后台全面解析
2016/04/11 Javascript
jQuery+ajax+asp.net获取Json值的方法
2016/06/08 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
微信小程序使用echarts获取数据并生成折线图
2019/10/16 Javascript
HTML+JS实现“代码雨”效果源码(黑客帝国文字下落效果)
2020/03/17 Javascript
[03:55]显微镜下的DOTA2特别篇——430灰烬之灵神级操作
2014/06/24 DOTA
python3使用PyMysql连接mysql数据库实例
2017/02/07 Python
Python反射的用法实例分析
2018/02/11 Python
python中字符串内置函数的用法总结
2018/09/13 Python
Python 微信之获取好友昵称并制作wordcloud的实例
2019/02/21 Python
Python3.4学习笔记之类型判断,异常处理,终止程序操作小结
2019/03/01 Python
Pycharm+Python+PyQt5使用详解
2019/09/25 Python
Window系统下Python如何安装OpenCV库
2020/03/05 Python
Python使用Pyqt5实现简易浏览器(最新版本测试过)
2020/04/27 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
Python调用Redis的示例代码
2020/11/24 Python
Html5中localStorage存储JSON数据并读取JSON数据的实现方法
2017/02/13 HTML / CSS
全球度假村:Club Med
2017/11/27 全球购物
澳大利亚儿童精品仓库:Goo & Co.
2019/06/20 全球购物
斯洛伐克香水和化妆品购物网站:Parfemy-Elnino.sk
2020/01/28 全球购物
介绍一下Java中的static关键字
2012/05/12 面试题
校班主任推荐信范文
2013/12/03 职场文书
小学生国庆演讲稿
2014/09/05 职场文书
公民代理授权委托书
2014/09/24 职场文书
教师党员学习十八届四中全会思想汇报
2014/11/03 职场文书
大学生预备党员自我评价
2015/03/04 职场文书
基于PyQT5制作一个桌面摸鱼工具
2022/02/15 Python
python Tkinter模块使用方法详解
2022/04/07 Python