const image = 'https://tdesign.gtimg.com/mobile/demos/example1.png'; const items = new Array(12).fill().map((_, index) => ({ label: index % 3 === 2 ? '最多六个文字' : '标题文字', image: image, })); 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), }, ], navbarHeight: 0, }, onLoad() { const query = wx.createSelectorQuery().in(this); const { sideBarIndex } = this.data; query.selectAll('.title').boundingClientRect(); query.select('.custom-navbar').boundingClientRect(); query.exec((res) => { const [rects, { height: navbarHeight }] = res; this.offsetTopList = rects.map((item) => item.top - navbarHeight); this.setData({ navbarHeight, scrollTop: this.offsetTopList[sideBarIndex] }); }); }, 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 }); } }, });