Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Navbar): Fixed getRect caused navbar position to be inaccurate #3286

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/navbar/__test__/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ exports[`navbar :base 1`] = `
<t-navbar>
<wx-view
class="t-navbar t-navbar--fixed t-navbar--visible-animation class t-class"
style="--td-navbar-padding-top: 20px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px; --td-navbar-right: 94px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px;"
style="--td-navbar-padding-top: 20px; --td-navbar-right: 94px; --td-navbar-left-max-width: 281px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px;"
>
<wx-view
class="t-navbar__placeholder t-class-placeholder"
Expand Down Expand Up @@ -40,7 +40,7 @@ exports[`navbar :base 2`] = `
<t-navbar>
<wx-view
class="t-navbar t-navbar--fixed t-navbar--hide-animation class t-class"
style="--td-navbar-padding-top: 20px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px; --td-navbar-right: 94px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px;"
style="--td-navbar-padding-top: 20px; --td-navbar-right: 94px; --td-navbar-left-max-width: 281px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px;"
>
<wx-view
class="t-navbar__placeholder t-class-placeholder"
Expand Down Expand Up @@ -75,7 +75,7 @@ exports[`navbar :base 3`] = `
<t-navbar>
<wx-view
class="t-navbar t-navbar--fixed t-navbar--hide class t-class"
style="--td-navbar-padding-top: 20px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px; --td-navbar-right: 94px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px;"
style="--td-navbar-padding-top: 20px; --td-navbar-right: 94px; --td-navbar-left-max-width: 281px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px;"
>
<wx-view
class="t-navbar__placeholder t-class-placeholder"
Expand Down Expand Up @@ -110,7 +110,7 @@ exports[`navbar :fixed 1`] = `
<t-navbar>
<wx-view
class="t-navbar t-navbar--fixed t-navbar--visible-animation class t-class"
style="--td-navbar-padding-top: 20px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px; --td-navbar-right: 94px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px;"
style="--td-navbar-padding-top: 20px; --td-navbar-right: 94px; --td-navbar-left-max-width: 281px; --td-navbar-capsule-height: 32px; --td-navbar-capsule-width: 87px; --td-navbar-height: 40px; --td-navbar-center-left: 94px; --td-navbar-center-width: 187px;"
>
<wx-view
class="t-navbar__placeholder t-class-placeholder"
Expand Down Expand Up @@ -145,7 +145,7 @@ exports[`navbar :menu button 1`] = `
<t-navbar>
<wx-view
class="t-navbar t-navbar--fixed class t-class"
style="--td-navbar-padding-top: 20px; --td-navbar-center-left: 375px; --td-navbar-center-width: -375px; --td-navbar-right: 375px; --td-navbar-capsule-height: 10px; --td-navbar-capsule-width: 40px; --td-navbar-height: -10px;"
style="--td-navbar-padding-top: 20px; --td-navbar-right: 375px; --td-navbar-left-max-width: 0px; --td-navbar-capsule-height: 10px; --td-navbar-capsule-width: 40px; --td-navbar-height: -10px; --td-navbar-center-left: 375px; --td-navbar-center-width: 0px;"
>
<wx-view
class="t-navbar__placeholder t-class-placeholder"
Expand Down
4 changes: 2 additions & 2 deletions src/navbar/navbar.less
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
@navbar-capsule-border-radius: var(--td-navbar-capsule-border-radius, 16px);
@navbar-capsule-width: var(--td-navbar-capsule-width, 88px);
@navbar-capsule-height: var(--td-navbar-capsule-height, 32px);
// var(--capsule-height)

.@{prefix}-navbar {
&--fixed {
Expand Down Expand Up @@ -78,7 +77,8 @@
&__left {
position: relative;
box-sizing: border-box;
// width: @navbar-right;
max-width: var(--td-navbar-left-max-width);
overflow: hidden;
display: flex;
align-items: center;
margin-left: @spacer-1;
Expand Down
124 changes: 86 additions & 38 deletions src/navbar/navbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export default class Navbar extends SuperComponent {
}, 300);
}
},

'title,titleMaxLength'(this: any) {
const { title } = this.properties;
const titleMaxLength = this.properties.titleMaxLength || Number.MAX_SAFE_INTEGER;
Expand All @@ -65,50 +66,96 @@ export default class Navbar extends SuperComponent {
showTitle: '',
hideLeft: false, // 隐藏左侧内容
hideCenter: false, // 隐藏中部内容
_menuRect: null, // 胶囊按钮节点信息
_leftRect: null, // 左侧节点信息
_boxStyle: {}, // 记录样式
};

async attached() {
// 场景值为1177(视频号直播间)和1175 (视频号profile页)时,小程序禁用了 wx.getMenuButtonBoundingClientRect
let rect = null;
if (wx.getMenuButtonBoundingClientRect) {
rect = wx.getMenuButtonBoundingClientRect();
}
if (!rect || !systemInfo) return;

const { right } = await getRect(this, `.${name}__left`);

const boxStyleList = [];
boxStyleList.push(`--td-navbar-padding-top: ${systemInfo.statusBarHeight}px`);
if (rect && systemInfo?.windowWidth) {
const maxSpacing = Math.max(right, systemInfo.windowWidth - rect.left);
boxStyleList.push(`--td-navbar-center-left: ${maxSpacing}px`); // 标题左侧距离
boxStyleList.push(`--td-navbar-center-width: ${rect.left - maxSpacing}px`); // 标题宽度
boxStyleList.push(`--td-navbar-right: ${systemInfo.windowWidth - rect.left}px`); // 导航栏右侧小程序胶囊按钮宽度
}
boxStyleList.push(`--td-navbar-capsule-height: ${rect.height}px`); // 胶囊高度
boxStyleList.push(`--td-navbar-capsule-width: ${rect.width}px`); // 胶囊宽度
boxStyleList.push(`--td-navbar-height: ${(rect.top - systemInfo.statusBarHeight) * 2 + rect.height}px`);
this.setData({
boxStyle: `${boxStyleList.join('; ')}`,
});
// @ts-ignore
if (wx.onMenuButtonBoundingClientRectWeightChange) {
// fixme: 规避单元测试无法识别新api,更新后可删除
// @ts-ignore
wx.onMenuButtonBoundingClientRectWeightChange((res: object) => this.queryElements(res)); // 监听胶囊条长度变化,隐藏遮挡的内容
}
attached() {
this.initStyle();
this.getLeftRect();
this.onMenuButtonBoundingClientRectWeightChange();
}

detached() {
// @ts-ignore
if (wx.offMenuButtonBoundingClientRectWeightChange) {
// fixme: 规避单元测试无法识别新api,更新后可删除
// @ts-ignore
wx.offMenuButtonBoundingClientRectWeightChange((res: object) => this.queryElements(res));
}
this.offMenuButtonBoundingClientRectWeightChange();
}

methods = {
initStyle() {
this.getMenuRect();

const { _menuRect, _leftRect } = this.data;

if (!_menuRect || !_leftRect || !systemInfo) return;

const _boxStyle = {
'--td-navbar-padding-top': `${systemInfo.statusBarHeight}px`,
'--td-navbar-right': `${systemInfo.windowWidth - _menuRect.left}px`, // 导航栏右侧小程序胶囊按钮宽度
'--td-navbar-left-max-width': `${_menuRect.left}px`, // 左侧内容最大宽度
'--td-navbar-capsule-height': `${_menuRect.height}px`, // 胶囊高度
'--td-navbar-capsule-width': `${_menuRect.width}px`, // 胶囊宽度
'--td-navbar-height': `${(_menuRect.top - systemInfo.statusBarHeight) * 2 + _menuRect.height}px`,
};

this.calcCenterStyle(_leftRect, _menuRect, _boxStyle);
},

calcCenterStyle(
leftRect: WechatMiniprogram.BoundingClientRectResult,
menuRect: WechatMiniprogram.BoundingClientRectResult,
defaultStyle: object,
) {
const maxSpacing = Math.max(leftRect.right, systemInfo.windowWidth - menuRect.left);
const _boxStyle = {
...defaultStyle,
'--td-navbar-center-left': `${maxSpacing}px`, // 标题左侧距离
'--td-navbar-center-width': `${Math.max(menuRect.left - maxSpacing, 0)}px`, // 标题宽度
};

const boxStyle = Object.entries(_boxStyle)
.map(([k, v]) => `${k}: ${v}`)
.join('; ');

this.setData({
boxStyle,
_boxStyle,
});
},

getLeftRect() {
getRect(this, `.${name}__left`).then((res) => {
if (res.right > this.data._leftRect.right) {
this.calcCenterStyle(res, this.data._menuRect, this.data._boxStyle);
}
});
},

getMenuRect() {
// 场景值为1177(视频号直播间)和1175 (视频号profile页)时,小程序禁用了 wx.getMenuButtonBoundingClientRect
if (wx.getMenuButtonBoundingClientRect) {
const rect = wx.getMenuButtonBoundingClientRect();
this.setData({
_menuRect: rect,
_leftRect: {
right: systemInfo.windowWidth - rect.left,
},
});
}
},

onMenuButtonBoundingClientRectWeightChange() {
if (wx.onMenuButtonBoundingClientRectWeightChange) {
wx.onMenuButtonBoundingClientRectWeightChange((res: object) => this.queryElements(res)); // 监听胶囊条长度变化,隐藏遮挡的内容
}
},

offMenuButtonBoundingClientRectWeightChange() {
if (wx.offMenuButtonBoundingClientRectWeightChange) {
wx.offMenuButtonBoundingClientRectWeightChange((res: object) => this.queryElements(res));
}
},

/**
* 比较胶囊条和navbar内容,决定是否隐藏
* @param capsuleRect API返回值,胶囊条的位置信息
Expand All @@ -118,12 +165,13 @@ export default class Navbar extends SuperComponent {
getRect(this, `.${this.data.classPrefix}__left`),
getRect(this, `.${this.data.classPrefix}__center`),
]).then(([leftRect, centerRect]) => {
if (leftRect.right > capsuleRect.left) {
// 部分安卓机型中(目前仅在Magic6/7中复现),仍存在精度问题,暂使用 Math.round() 取整规避
if (Math.round(leftRect.right) > capsuleRect.left) {
this.setData({
hideLeft: true,
hideCenter: true,
});
} else if (centerRect.right > capsuleRect.left) {
} else if (Math.round(centerRect.right) > capsuleRect.left) {
this.setData({
hideLeft: false,
hideCenter: true,
Expand Down