程序员玛丽的星海方舟

微信小程序:灵活适配不同标题栏高度的设备的方法

工程需求

开发的应用:用微信小程序经由hera生成的跨平台移动端App。

作为实习生在工作中遇到了这样的需求:需要顶部的标题栏和选择标签栏保持一直在窗口顶部(样式即top:0; position:fixed;),而其他的内容组件则可以随着页面滚动(样式即position:absolute;)。而我开发的小程序属于跨平台App,不知道公司的标题栏大小是如何设置的,总之会产生不同设备上标题栏高度不一的问题(尤其体现在微信小程序和hera生成的Android/IOS应用之间)。那么则需要解决一个问题,如何让absolute的内容组件自动贴着fixed的顶部组件生成呢?

首先,对于需要分别设置不同position的组件,当然不能使用flex布局之类的进行自动黏贴。那么接下来的想法是想办法获取fixed部分的底部高度。

方案参考

在公司其他员工的代码中发现了这样的操作:在html页面中建立一个wxs脚本,运行时获取设备是否为Android,如果是则通过Android系统接口获取标题栏高度而进行对固定内容组件的top样式的渲染,否则就不要使用位置fixed。

私以为,还能够用更优雅的代码和适配性更强的方案去解决这个问题,于是经过一番思考有了以下的方案:

最终方案

大体思路如下:

在onLoad函数中使用微信小程序的SelectorQuery选取需要设置fixed的view,然后获取它的底部高度,再对需要设置absolute的内容组件的top样式进行渲染。

主要代码:

index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* page */
data: {
dAbsoluteTop: 0, //准备设置固定内容组件的高度
},

onLoad: function(){
const that = this;
const query = wx.createSelectorQuery();
query.select('#fixed-view').boundingClientRect();
query.selectViewport().scrollOffset();
query.exec(function(res){
that.setData({
dAbsoluteTop: res[0].bottom //根据底部渲染
});
});
},
index.wxml
1
2
3
4
5
6
7
<view id="fixed-view" style="position: fixed; top: 0; display: flex; flex-direction: column;">
<titlebar /> <!-- 标题栏 -->
<tabbar /> <!-- 选择标签栏 -->
</view>
<view style="position: absolute; top: {{dAbsolute}};">
<!-- 内容 -->
</view>

经不同设备检验,效果良好。