微信小程序吸底区域适配iPhoneX的实现


Posted in Javascript onApril 09, 2020

微信小程序适配iPhone X主要针对fix定位到底部的区域,比如详情页或购物车底部的按钮栏,会与iPhone X的Home Indicator横条重叠,这样在点击下方按钮时很容易误触发手势操作,如下图:

微信小程序吸底区域适配iPhoneX的实现

旧方法

1. 获取设备信息

/**
 * 获取设备信息
 * @returns {Promise<any>}
 */
export function wechatGetSystemInfo () {
 return new Promise((resolve, reject) => {
  wx.getSystemInfo({
   success: (res) => {
    resolve(res)
   }, fail: (err) => {
    reject(err)
   }
  })
 })
}

2. 设置css样式

.view-fix-iphonex {
 bottom: ~'68rpx' !important;
}

.view-fix-iphonex::after {
 content: ' ';
 position: fixed;
 bottom: 0 !important;
 height: ~'68rpx' !important;
 width: 100%;
 background: #fff;
}

3. 设置一个标识符isIpx存在vuex中,在小程序初始化完成时判断

App.vue 中处理

<script>
 import wx from 'wx'
 import { mapGetters, mapActions } from 'vuex'
 import { wechatGetSystemInfo } from './utils/weappUtils'

 export default {
  onLaunch () {
   this.isIphoneX()
  },
  computed: {
   ...mapGetters(['isIpx'])
  },
  methods: {
   //判断设备是否是iphoneX
   isIphoneX() {
    wechatGetSystemInfo().then(res => {
     const deviceModel = 'iPhone X'
     let isIpx = false
     if (res.model.indexOf(deviceModel) > -1) {
      isIpx = true
     }
     if (this.isIpx !== isIpx) {
      this.setIsIpx(isIpx)
     }
    }).catch(err => {})
   },
   ...mapActions(['setIsIpx'])
  }
 }
</script>

4. 在需要适配的页面中设置

如在 demo.vue 中处理

<template>
   <div class="fix-view"
     :class="isIpx?'view-fix-iphonex':''"
  >
   吸附在底部的区域
  </div>
</template>


<script>
 import wx from 'wx'
 import {mapGetters} from 'vuex'

 export default {
  computed: {
   ...mapGetters(['isIpx'])
  },
 }
</script>

<style lang="less">
  .fix-view {
   position: fixed;
   left: 0;
   right: 0;
   bottom: 0;
   height: ~'100rpx';
   line-height: ~'100rpx';
   box-sizing: border-box;
   text-align: right;
   display: flex;
   justify-content: end;
   background: #fff;
  }
</style>

新方法

env() 和 constant()

iOS11 新增特性,Webkit 的一个 CSS 函数,用于设定安全区域与边界的距离,有四个预定义的变量:

  • safe-area-inset-left:安全区域距离左边边界距离
  • safe-area-inset-right:安全区域距离右边边界距离
  • safe-area-inset-top:安全区域距离顶部边界距离
  • safe-area-inset-bottom:安全区域距离底部边界距离

这里我们只需要关注 safe-area-inset-bottom 这个变量,因为它对应的就是小黑条的高度(横竖屏时值不一样)。

注意:当 viewport-fit=contain 时 env() 是不起作用的,必须要配合 viewport-fit=cover 使用。对于不支持env() 的浏览器,浏览器将会忽略它。

在这之前,笔者使用的是 constant(),后来,官方文档加了这么一段注释(坑):

The env() function shipped in iOS 11 with the name constant(). Beginning with Safari Technology Preview 41 and the iOS 11.2 beta, constant() has been removed and replaced with env(). You can use the CSS fallback mechanism to support both versions, if necessary, but should prefer env() going forward.

这就意味着,之前使用的 constant() 在 iOS11.2 之后就不能使用的,但我们还是需要做向后兼容,像这样:

padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS < 11.2 */
padding-bottom: env(safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */

注意:env() 跟 constant() 需要同时存在,而且顺序不能换。

更详细说明,参考文档:Designing Websites for iPhone X

如何适配

了解了以上所说的几个知识点,接下来我们适配的思路就很清晰了。

第一步:设置网页在可视窗口的布局方式

新增 viweport-fit 属性,使得页面内容完全覆盖整个窗口:

<meta name="viewport" content="width=device-width, viewport-fit=cover">

前面也有提到过,只有设置了 viewport-fit=cover,才能使用 env()。

第二步:页面主体内容限定在安全区域内

这一步根据实际页面场景选择,如果不设置这个值,可能存在小黑条遮挡页面最底部内容的情况。

body { 
	padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

第三步:fixed 元素的适配类型一:fixed 完全吸底元素(bottom = 0),比如下图这两种情况:

微信小程序吸底区域适配iPhoneX的实现

可以通过加内边距 padding 扩展高度:

{ 
	padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

或者通过计算函数 calc 覆盖原来高度:

{ 
	height: calc(60px(假设值) + constant(safe-area-inset-bottom));
  height: calc(60px(假设值) + env(safe-area-inset-bottom));
}

注意,这个方案需要吸底条必须是有背景色的,因为扩展的部分背景是跟随外容器的,否则出现镂空情况。

还有一种方案就是,可以通过新增一个新的元素(空的颜色块,主要用于小黑条高度的占位),然后吸底元素可以不改变高度只需要调整位置,像这样:

{ 
	margin-bottom: constant(safe-area-inset-bottom);
  margin-bottom: env(safe-area-inset-bottom);
}

空的颜色块:

{ 
	position: fixed;
  bottom: 0;
  width: 100%;
  height: constant(safe-area-inset-bottom);
  height: env(safe-area-inset-bottom);
  background-color: #fff;
}

类型二:fixed 非完全吸底元素(bottom ≠ 0),比如 “返回顶部”、“侧边广告” 等

像这种只是位置需要对应向上调整,可以仅通过外边距 margin 来处理:

{ 
	margin-bottom: constant(safe-area-inset-bottom);
  margin-bottom: env(safe-area-inset-bottom);
}

或者,你也可以通过计算函数 calc 覆盖原来 bottom 值:

{ 
	bottom: calc(50px(假设值) + constant(safe-area-inset-bottom));
  bottom: calc(50px(假设值) + env(safe-area-inset-bottom));
}

你也可以使用 @supports 隔离兼容样式

写到这里,我们常见的两种类型的 fixed 元素适配方案已经了解了吧。如果我们只希望 iPhoneX 才需要新增适配样式,我们可以配合 @supports 来隔离兼容样式,当然这个处理对页面展示实际不会有任何影响:

@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) { 
	div {
  	margin-bottom: constant(safe-area-inset-bottom);
    margin-bottom: env(safe-area-inset-bottom); 
  }
}

到此这篇关于微信小程序吸底区域适配iPhoneX的实现的文章就介绍到这了,更多相关小程序吸底区域适配iPhoneX内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
window.onload 加载完毕的问题及解决方案(上)
Jul 09 Javascript
jQuery制作简洁的多级联动Select下拉框
Dec 23 Javascript
node-http-proxy修改响应结果实例代码
Jun 06 Javascript
jQuery tagsinput在h5邮件客户端中应用详解
Sep 26 Javascript
基于jQuery实现Accordion手风琴自定义插件
Oct 13 Javascript
深入理解选择框脚本[推荐]
Dec 13 Javascript
bootstrap轮播图示例代码分享
May 17 Javascript
谈谈为什么你的 JavaScript 代码如此冗长
Jan 30 Javascript
React中获取数据的3种方法及优缺点
Feb 18 Javascript
详解微信小程序工程化探索之webpack实战
Apr 20 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
Jul 09 Javascript
如何利用vue实现波谱拟合详解
Nov 05 Javascript
加速vue组件渲染之性能优化
Apr 09 #Javascript
javascript设计模式 ? 抽象工厂模式原理与应用实例分析
Apr 09 #Javascript
javascript设计模式 ? 工厂模式原理与应用实例分析
Apr 09 #Javascript
javascript设计模式 ? 简单工厂模式原理与应用实例分析
Apr 09 #Javascript
javascript设计模式 ? 单例模式原理与应用实例分析
Apr 09 #Javascript
微信小程序纯文本实现@功能
Apr 08 #Javascript
JavaScript 俄罗斯方块游戏实现方法与代码解释
Apr 08 #Javascript
You might like
php+dojo 的数据库保存拖动布局的一个方法dojo 这里下载
2007/03/07 PHP
PHP中常用的转义函数
2014/02/28 PHP
PHP JSON格式的中文显示问题解决方法
2015/04/09 PHP
PHP中FTP相关函数小结
2016/07/15 PHP
php通过pecl方式安装扩展的实例讲解
2018/02/02 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
ie focus bug 解决方法
2009/09/03 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
Extjs中DisplayField的日期或者数字格式化扩展
2010/09/03 Javascript
40个有创意的jQuery图片、内容滑动及弹出插件收藏集之一
2011/12/31 Javascript
jquery实现导航固定顶部的效果仿蘑菇街
2014/10/22 Javascript
jQuery获取Table某列的值(推荐)
2017/03/03 Javascript
Web纯前端“旭日图”实现元素周期表
2017/03/10 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
2018/01/23 Javascript
使用Ajax和Jquery配合数据库实现下拉框的二级联动的示例
2018/01/25 jQuery
nodejs实现解析xml字符串为对象的方法示例
2018/03/14 NodeJs
详解Vue之父子组件传值
2019/04/01 Javascript
浅谈vue中document.getElementById()拿到的是原值的问题
2020/07/26 Javascript
分享一个常用的Python模拟登陆类
2015/03/29 Python
Python基于sftp及rsa密匙实现远程拷贝文件的方法
2016/09/21 Python
python2.7实现FTP文件下载功能
2018/04/15 Python
Python实现合并两个列表的方法分析
2018/05/28 Python
使用11行Python代码盗取了室友的U盘内容
2018/10/23 Python
对Python+opencv将图片生成视频的实例详解
2019/01/08 Python
Python设计模式之解释器模式原理与用法实例分析
2019/01/10 Python
浅谈python的输入输出,注释,基本数据类型
2019/04/02 Python
Python实现的排列组合、破解密码算法示例
2019/04/12 Python
tensorflow的ckpt及pb模型持久化方式及转化详解
2020/02/12 Python
Pytorch 使用 nii数据做输入数据的操作
2020/05/26 Python
体验完美剃须:The Art of Shaving
2018/08/06 全球购物
意大利在线购买隐形眼镜网站:VisionDirect.it
2019/03/18 全球购物
Watchshop德国:欧洲在线手表No.1
2019/06/20 全球购物
工程力学硕士生的自我评价范文
2013/11/16 职场文书
团委书记的竞聘演讲稿
2014/04/24 职场文书
高一学生评语大全
2014/04/25 职场文书
大学学生个人总结
2015/02/15 职场文书