详解小程序横屏方案对比


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 相关文章推荐
JavaScript方法和技巧大全
Dec 27 Javascript
Array.prototype 的泛型应用分析
Apr 30 Javascript
EasyUI的treegrid组件动态加载数据问题的解决办法
Dec 11 Javascript
firefox浏览器不支持innerText的解决方法
Aug 07 Javascript
JavaScript动态修改弹出窗口大小的方法
Apr 06 Javascript
对js eval()函数的一些见解
Aug 15 Javascript
基于jQuery实现中英文切换导航条效果
Sep 18 Javascript
AngularJS 文件上传控件 ng-file-upload详解
Jan 13 Javascript
js中DOM三级列表(代码分享)
Mar 20 Javascript
vue根据进入的路由进行原路返回的方法
Sep 26 Javascript
js html实现计算器功能
Nov 13 Javascript
node实现mock-plugin中间件的方法
Dec 25 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
关于url地址传参数时字符串有回车造成页面脚本赋值失败的解决方法
2013/06/28 PHP
对于ThinkPHP框架早期版本的一个SQL注入漏洞详细分析
2014/07/04 PHP
PHP自动生成缩略图函数的源码示例
2019/03/18 PHP
浅谈PHP5.6 与 PHP7.0 区别
2019/10/09 PHP
Javascript学习笔记1 数据类型
2010/01/11 Javascript
JavaScript对象之间的转换 jQuery对象和原声DOM
2011/03/07 Javascript
jquery利用event.which方法获取键盘输入值的代码
2011/10/09 Javascript
js实现正方形颜色从下往上升的效果
2014/08/04 Javascript
浅析AngularJS Filter用法
2015/12/28 Javascript
基于JS实现Android,iOS一个手势动画效果
2016/04/27 Javascript
AngularJS入门教程之XHR和依赖注入详解
2016/08/18 Javascript
利用C/C++编写node.js原生模块的方法教程
2017/07/07 Javascript
深入了解javascript 数组的sort方法
2018/06/01 Javascript
vue实现todolist基本功能以及数据存储功能实例详解
2019/04/11 Javascript
浅谈JavaScript中的“!!”作用
2020/08/03 Javascript
vant时间控件使用方法详解
2020/12/24 Javascript
利用PyInstaller将python程序.py转为.exe的方法详解
2017/05/03 Python
Python之Scrapy爬虫框架安装及使用详解
2017/11/16 Python
python3+PyQt5使用数据库窗口视图
2018/04/24 Python
Python 最大概率法进行汉语切分的方法
2018/12/14 Python
Django 外键的使用方法详解
2019/07/19 Python
python微信公众号开发简单流程实现
2020/03/09 Python
keras中的History对象用法
2020/06/19 Python
Python 利用Entrez库筛选下载PubMed文献摘要的示例
2020/11/24 Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
2021/02/06 Python
Html5页面点击遮罩层背景关闭遮罩层
2020/11/30 HTML / CSS
美国领先的家居装饰和礼品商店:Kirkland’s
2017/01/30 全球购物
迟到检讨书800字
2014/01/13 职场文书
大学毕业生个人自荐书
2014/07/02 职场文书
单位工作证明格式模板
2014/10/04 职场文书
公积金接收函格式
2015/01/30 职场文书
护士实习自荐信
2015/03/06 职场文书
苦儿流浪记读书笔记
2015/07/01 职场文书
学会感恩主题班会
2015/08/12 职场文书
老干部局2015年度工作总结
2015/10/22 职场文书
springboot+zookeeper实现分布式锁
2022/03/21 Java/Android