safeArea.js
3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
export const getSafeArea = () => {
// 获取系统信息(UniApp 跨端 API)
const systemInfo = uni.getSystemInfoSync();
// 顶部状态栏高度(所有机型都有,非安全区但常用)
const statusBarHeight = systemInfo.statusBarHeight || 0;
// 底部安全距离(全面屏/刘海屏机型有值,非全面屏为 0)
let safeAreaInsetBottom = systemInfo.safeAreaInsets?.bottom || 0;
// 兼容旧版小程序(部分机型 safeAreaInsets 可能不存在)
if (typeof safeAreaInsetBottom !== 'number') {
const safeArea = systemInfo.safeArea || {};
safeAreaInsetBottom = systemInfo.screenHeight - (safeArea.bottom || systemInfo.screenHeight);
}
// 胶囊按钮默认信息(适配非微信小程序端:H5、App、其他小程序)
const menuButtonInfo = {
height: 32, // 默认胶囊高度(符合常见设计规范)
width: 80, // 默认胶囊宽度
top: statusBarHeight + 4, // 默认顶部位置(状态栏下4px)
bottom: statusBarHeight + 36, // 默认底部位置(状态栏高度 + 胶囊高度)
right: 16, // 默认右侧位置(距离屏幕左边16px)
};
// 【关键修复】仅在微信小程序环境中获取真实胶囊信息
// 判断微信小程序环境:通过 systemInfo.appPlatform === 'mp-weixin'(UniApp 统一判断标准)
if (systemInfo.appPlatform === 'mp-weixin') {
try {
// 微信小程序专属 API:获取胶囊菜单信息
const menuBtn = uni.getMenuButtonBoundingClientRect();
// 验证返回结果有效(避免 null/undefined)
if (menuBtn && typeof menuBtn.height === 'number' && menuBtn.height > 0) {
menuButtonInfo.height = menuBtn.height;
menuButtonInfo.width = menuBtn.width || 80;
menuButtonInfo.top = menuBtn.top || statusBarHeight + 4;
menuButtonInfo.bottom = menuBtn.bottom || statusBarHeight + 36;
menuButtonInfo.right = menuBtn.right || 16;
}
} catch (e) {
// 异常时保留默认值,不影响整体功能
console.warn('微信小程序获取胶囊信息失败,使用默认值:', e);
}
}
return {
statusBarHeight,
safeAreaInsetBottom,
menuButtonInfo,
};
};
/**
* 快捷获取顶部安全距离(状态栏高度)
* @returns {number} 顶部状态栏高度(px)
*/
export const getTopSafeArea = () => {
return getSafeArea().statusBarHeight;
};
/**
* 快捷获取底部安全距离
* @returns {number} 底部安全距离(px)
*/
export const getBottomSafeArea = () => {
return getSafeArea().safeAreaInsetBottom;
};
/**
* 快捷获取胶囊按钮高度
* @returns {number} 胶囊高度(px)(微信小程序返回真实值,其他端返回默认32px)
*/
export const getMenuButtonHeight = () => {
return getSafeArea().menuButtonInfo.height;
};
/**
* 快捷获取胶囊按钮宽度
* @returns {number} 胶囊宽度(px)(微信小程序返回真实值,其他端返回默认80px)
*/
export const getMenuButtonWidth = () => {
return getSafeArea().menuButtonInfo.width;
};
/** 获取 wd-navbar 导航栏高度 */
export function getNavbarHeight() {
const systemInfo = uni.getSystemInfoSync();
const statusBarHeight = systemInfo.statusBarHeight || 0;
// #ifdef MP-WEIXIN
// 小程序:根据胶囊按钮位置计算导航栏高度,确保内容与胶囊垂直居中
const menuButtonInfo = uni.getMenuButtonBoundingClientRect();
// 导航栏高度 = (胶囊顶部到状态栏底部的距离) * 2 + 胶囊高度
const navBarHeight = (menuButtonInfo.top - statusBarHeight) * 2 + menuButtonInfo.height;
return statusBarHeight + navBarHeight;
// #endif
// #ifndef MP-WEIXIN
// H5/App:状态栏高度 + 导航栏高度(44px)
return statusBarHeight + 44;
// #endif
}