From 1ede3c595ff6b364ae8f944b807768480f235071 Mon Sep 17 00:00:00 2001 From: jarmywang Date: Wed, 13 Nov 2024 23:37:31 +0800 Subject: [PATCH 1/4] fix(Navbar): Fixed getRect caused the navbar position to be inaccurate for a long time --- src/navbar/navbar.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/navbar/navbar.ts b/src/navbar/navbar.ts index df1f1d637..2f5faef1a 100644 --- a/src/navbar/navbar.ts +++ b/src/navbar/navbar.ts @@ -75,8 +75,7 @@ export default class Navbar extends SuperComponent { } if (!rect || !systemInfo) return; - const { right } = await getRect(this, `.${name}__left`); - + const right = 36; const boxStyleList = []; boxStyleList.push(`--td-navbar-padding-top: ${systemInfo.statusBarHeight}px`); if (rect && systemInfo?.windowWidth) { @@ -84,6 +83,18 @@ export default class Navbar extends SuperComponent { 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`); // 导航栏右侧小程序胶囊按钮宽度 + + // getRect方法耗时较长,真机约600ms,会导致navbar位置长时间不准确,所以先设置默认值,再异步获取 + getRect(this, `.${name}__left`).then((rect2) => { + if (rect2.right !== right) { + const boxStyleList2 = boxStyleList.filter((item) => !item.startsWith('--td-navbar-center-left')); + const maxSpacing2 = Math.max(rect2.right, systemInfo.windowWidth - rect.left); + boxStyleList2.push(`--td-navbar-center-left: ${maxSpacing2}px`); + this.setData({ + boxStyle: `${boxStyleList2.join('; ')}`, + }); + } + }); } boxStyleList.push(`--td-navbar-capsule-height: ${rect.height}px`); // 胶囊高度 boxStyleList.push(`--td-navbar-capsule-width: ${rect.width}px`); // 胶囊宽度 From 863f90ff48b152f723a6337de5d962723f487fdf Mon Sep 17 00:00:00 2001 From: jarmywang Date: Thu, 14 Nov 2024 09:45:26 +0800 Subject: [PATCH 2/4] fix(Navbar): update snap --- src/navbar/__test__/__snapshots__/index.test.js.snap | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/navbar/__test__/__snapshots__/index.test.js.snap b/src/navbar/__test__/__snapshots__/index.test.js.snap index 0451a59be..c82e89ca5 100644 --- a/src/navbar/__test__/__snapshots__/index.test.js.snap +++ b/src/navbar/__test__/__snapshots__/index.test.js.snap @@ -5,7 +5,7 @@ exports[`navbar :base 1`] = ` Date: Wed, 27 Nov 2024 12:42:12 +0800 Subject: [PATCH 3/4] chore: optimize --- .../__test__/__snapshots__/index.test.js.snap | 10 +- src/navbar/navbar.less | 4 +- src/navbar/navbar.ts | 133 +++++++++++------- 3 files changed, 91 insertions(+), 56 deletions(-) diff --git a/src/navbar/__test__/__snapshots__/index.test.js.snap b/src/navbar/__test__/__snapshots__/index.test.js.snap index c82e89ca5..f0192696e 100644 --- a/src/navbar/__test__/__snapshots__/index.test.js.snap +++ b/src/navbar/__test__/__snapshots__/index.test.js.snap @@ -5,7 +5,7 @@ exports[`navbar :base 1`] = ` { - if (rect2.right !== right) { - const boxStyleList2 = boxStyleList.filter((item) => !item.startsWith('--td-navbar-center-left')); - const maxSpacing2 = Math.max(rect2.right, systemInfo.windowWidth - rect.left); - boxStyleList2.push(`--td-navbar-center-left: ${maxSpacing2}px`); - this.setData({ - boxStyle: `${boxStyleList2.join('; ')}`, - }); - } - }); - } - 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 _boxStyleList = {}; + _boxStyleList['--td-navbar-padding-top'] = `${systemInfo.statusBarHeight}px`; + _boxStyleList['--td-navbar-right'] = `${systemInfo.windowWidth - _menuRect.left}px`; // 导航栏右侧小程序胶囊按钮宽度 + _boxStyleList['--td-navbar-left-max-width'] = `${_menuRect.left}px`; // 左侧内容最大宽度 + _boxStyleList['--td-navbar-capsule-height'] = `${_menuRect.height}px`; // 胶囊高度 + _boxStyleList['--td-navbar-capsule-width'] = `${_menuRect.width}px`; // 胶囊宽度 + _boxStyleList['--td-navbar-height'] = `${(_menuRect.top - systemInfo.statusBarHeight) * 2 + _menuRect.height}px`; + + this.calcCenterStyle(_leftRect, _menuRect, _boxStyleList); + }, + + calcCenterStyle( + leftRect: WechatMiniprogram.BoundingClientRectResult, + menuRect: WechatMiniprogram.BoundingClientRectResult, + defaultStyle: object, + ) { + const maxSpacing = Math.max(leftRect.right, systemInfo.windowWidth - menuRect.left); + const _boxStyleObj = {}; + + _boxStyleObj['--td-navbar-center-left'] = `${maxSpacing}px`; // 标题左侧距离 + _boxStyleObj['--td-navbar-center-width'] = `${Math.max(menuRect.left - maxSpacing, 0)}px`; // 标题宽度 + + const boxStyle = Object.entries({ ...defaultStyle, ..._boxStyleObj }) + .map(([k, v]) => `${k}: ${v}`) + .join('; '); + + this.setData({ + boxStyle, + _boxStyle: { ...defaultStyle, ..._boxStyleObj }, + }); + }, + + 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返回值,胶囊条的位置信息 @@ -129,12 +163,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, From fde5c2faa4190d3d122660937f547fb42224490e Mon Sep 17 00:00:00 2001 From: betavs Date: Thu, 28 Nov 2024 14:54:00 +0800 Subject: [PATCH 4/4] perf(navbar): calc style --- src/navbar/navbar.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/navbar/navbar.ts b/src/navbar/navbar.ts index e64cd009b..a772a0a83 100644 --- a/src/navbar/navbar.ts +++ b/src/navbar/navbar.ts @@ -89,15 +89,16 @@ export default class Navbar extends SuperComponent { if (!_menuRect || !_leftRect || !systemInfo) return; - const _boxStyleList = {}; - _boxStyleList['--td-navbar-padding-top'] = `${systemInfo.statusBarHeight}px`; - _boxStyleList['--td-navbar-right'] = `${systemInfo.windowWidth - _menuRect.left}px`; // 导航栏右侧小程序胶囊按钮宽度 - _boxStyleList['--td-navbar-left-max-width'] = `${_menuRect.left}px`; // 左侧内容最大宽度 - _boxStyleList['--td-navbar-capsule-height'] = `${_menuRect.height}px`; // 胶囊高度 - _boxStyleList['--td-navbar-capsule-width'] = `${_menuRect.width}px`; // 胶囊宽度 - _boxStyleList['--td-navbar-height'] = `${(_menuRect.top - systemInfo.statusBarHeight) * 2 + _menuRect.height}px`; - - this.calcCenterStyle(_leftRect, _menuRect, _boxStyleList); + 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( @@ -106,18 +107,19 @@ export default class Navbar extends SuperComponent { defaultStyle: object, ) { const maxSpacing = Math.max(leftRect.right, systemInfo.windowWidth - menuRect.left); - const _boxStyleObj = {}; + const _boxStyle = { + ...defaultStyle, + '--td-navbar-center-left': `${maxSpacing}px`, // 标题左侧距离 + '--td-navbar-center-width': `${Math.max(menuRect.left - maxSpacing, 0)}px`, // 标题宽度 + }; - _boxStyleObj['--td-navbar-center-left'] = `${maxSpacing}px`; // 标题左侧距离 - _boxStyleObj['--td-navbar-center-width'] = `${Math.max(menuRect.left - maxSpacing, 0)}px`; // 标题宽度 - - const boxStyle = Object.entries({ ...defaultStyle, ..._boxStyleObj }) + const boxStyle = Object.entries(_boxStyle) .map(([k, v]) => `${k}: ${v}`) .join('; '); this.setData({ boxStyle, - _boxStyle: { ...defaultStyle, ..._boxStyleObj }, + _boxStyle, }); },