详解小程序横屏方案对比


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 22 Javascript
改善你的jQuery的25个步骤 千倍级效率提升
Feb 11 Javascript
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
Mar 24 Javascript
JS之Date对象和获取系统当前时间详解
Jan 13 Javascript
代码获取历史上的今天发生的事
Apr 11 Javascript
微信企业号开发之微信考勤百度地图定位
Sep 11 Javascript
javascript作用域链与执行环境详解
Mar 25 Javascript
react.js 获取真实的DOM节点实例(必看)
Apr 17 Javascript
基于AngularJS的拖拽文件上传的实例代码
Jul 15 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
Jul 02 Javascript
微信小程序 调用远程接口 给全局数组赋值代码实例
Aug 13 Javascript
微信小程序自定义yPicker组件实现省市区三级联动功能
Oct 29 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
PHP在特殊字符前加斜杠的实现代码
2011/07/17 PHP
PHP怎么实现网站保存快捷方式方便用户随时浏览
2013/08/15 PHP
PHP超全局数组(Superglobals)介绍
2015/07/01 PHP
PHP实现图片不变型裁剪及图片按比例裁剪的方法
2016/01/14 PHP
php 生成加密公钥加密私钥实例详解
2017/06/16 PHP
会自动逐行上升的文本框
2006/06/30 Javascript
js实现权限树的更新权限时的全选全消功能
2009/02/17 Javascript
javascript 日历提醒系统( 兼容所有浏览器 )
2009/04/07 Javascript
window.js 主要包含了页面的一些操作
2009/12/23 Javascript
jquery 图片 上一张 下一张 链接效果(续篇)
2010/04/20 Javascript
URL地址中的#符号使用说明
2011/02/12 Javascript
读jQuery之十 事件模块概述
2011/06/27 Javascript
CSS javascript 结合实现悬浮固定菜单效果
2015/08/23 Javascript
JS 面向对象之继承---多种组合继承详解
2016/07/10 Javascript
nodejs 子进程正确的打开方式
2017/07/03 NodeJs
JS从非数组对象转数组的方法小结
2018/03/26 Javascript
迅速了解一下ES10中Object.fromEntries的用法使用
2019/03/05 Javascript
Vue.js中的extend绑定节点并显示的方法
2019/06/20 Javascript
[01:10]为家乡而战!完美世界城市挑战赛全国总决赛花絮
2019/07/25 DOTA
python中元类用法实例
2014/10/10 Python
Python利用ansible分发处理任务
2015/08/04 Python
浅析Python编写函数装饰器
2016/03/18 Python
用python实现的线程池实例代码
2018/01/06 Python
python实现屏保计时器的示例代码
2018/08/08 Python
python单向链表的基本实现与使用方法【定义、遍历、添加、删除、查找等】
2019/10/24 Python
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
董事长职责范文
2013/11/08 职场文书
给排水工程师岗位职责
2013/11/21 职场文书
办公室前台的岗位职责
2013/12/20 职场文书
销售主管岗位职责
2014/02/08 职场文书
学生会主席演讲稿
2014/04/25 职场文书
学习党的群众路线对照检查材料
2014/09/29 职场文书
关于运动会的广播稿50字
2014/10/17 职场文书
2014年校务公开工作总结
2014/12/18 职场文书
HTML+css盒子模型案例(圆,半圆等)“border-radius” 简单易上手
2021/05/10 HTML / CSS
Python访问Redis的详细操作
2021/06/26 Python