const image = 'https://tdesign.gtimg.com/miniprogram/images/example2.png'; const items = new Array(12).fill({ label: '标题文字', image }, 0, 12); Page({ offsetTopList: [], data: { sideBarIndex: 1, scrollTop: 0, categories: [ { label: '选项一', title: '标题一', badgeProps: {}, items, }, { label: '选项二', title: '标题二', badgeProps: { dot: true, }, items: items.slice(0, 9), }, { label: '选项三', title: '标题三', badgeProps: {}, items: items.slice(0, 9), }, { label: '选项四', title: '标题四', badgeProps: { count: 6, }, items: items.slice(0, 6), }, { label: '选项五', title: '标题五', badgeProps: {}, items: items.slice(0, 3), }, ], }, onLoad() { const query = wx.createSelectorQuery().in(this); const { sideBarIndex } = this.data; query .selectAll('.title') .boundingClientRect((rects) => { this.offsetTopList = rects.map((item) => item.top); this.setData({ scrollTop: rects[sideBarIndex].top }); }) .exec(); }, onSideBarChange(e) { const { value } = e.detail; this.setData({ sideBarIndex: value, scrollTop: this.offsetTopList[value] }); }, onScroll(e) { const { scrollTop } = e.detail; const threshold = 50; // 下一个标题与顶部的距离 if (scrollTop < threshold) { this.setData({ sideBarIndex: 0 }); return; } const index = this.offsetTopList.findIndex((top) => top > scrollTop && top - scrollTop <= threshold); if (index > -1) { this.setData({ sideBarIndex: index }); } }, });