Skip to content

Commit c66b7bf

Browse files
authored
fix(side-bar): incorrect positioning during fast scrolling in the example (#3648)
1 parent f4e0df4 commit c66b7bf

File tree

3 files changed

+75
-21
lines changed

3 files changed

+75
-21
lines changed

src/side-bar/_example/base/index.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const items = new Array(12).fill().map((_, index) => ({
66

77
Page({
88
offsetTopList: [],
9+
lastScrollTop: 0,
910
data: {
1011
sideBarIndex: 1,
1112
scrollTop: 0,
@@ -67,16 +68,33 @@ Page({
6768
onScroll(e) {
6869
const { scrollTop } = e.detail;
6970
const threshold = 50; // 下一个标题与顶部的距离
71+
const direction = scrollTop > this.lastScrollTop ? 'down' : 'up';
72+
this.lastScrollTop = scrollTop;
7073

71-
if (scrollTop < threshold) {
72-
this.setData({ sideBarIndex: 0 });
73-
return;
74-
}
74+
// 动态调整阈值:向下滚动时增大阈值,向上时减小
75+
const dynamicThreshold = direction === 'down' ? threshold * 1.5 : threshold * 0.8;
76+
77+
// 使用二分查找优化查找效率
78+
const findNearestIndex = (arr, target) => {
79+
let left = 0;
80+
let right = arr.length - 1;
81+
let result = 0;
82+
while (left <= right) {
83+
const mid = Math.floor((left + right) / 2);
84+
if (arr[mid] <= target + dynamicThreshold) {
85+
result = mid;
86+
left = mid + 1;
87+
} else {
88+
right = mid - 1;
89+
}
90+
}
91+
return result;
92+
};
7593

76-
const index = this.offsetTopList.findIndex((top) => top > scrollTop && top - scrollTop <= threshold);
94+
const newIndex = findNearestIndex(this.offsetTopList, scrollTop);
7795

78-
if (index > -1) {
79-
this.setData({ sideBarIndex: index });
96+
if (newIndex !== this.data.sideBarIndex) {
97+
this.setData({ sideBarIndex: newIndex });
8098
}
8199
},
82100
});

src/side-bar/_example/custom/index.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const items = new Array(12).fill().map((_, index) => ({
66

77
Page({
88
offsetTopList: [],
9+
lastScrollTop: 0,
910
data: {
1011
sideBarIndex: 1,
1112
scrollTop: 0,
@@ -66,16 +67,33 @@ Page({
6667
onScroll(e) {
6768
const { scrollTop } = e.detail;
6869
const threshold = 50; // 下一个标题与顶部的距离
70+
const direction = scrollTop > this.lastScrollTop ? 'down' : 'up';
71+
this.lastScrollTop = scrollTop;
6972

70-
if (scrollTop < threshold) {
71-
this.setData({ sideBarIndex: 0 });
72-
return;
73-
}
73+
// 动态调整阈值:向下滚动时增大阈值,向上时减小
74+
const dynamicThreshold = direction === 'down' ? threshold * 1.5 : threshold * 0.8;
75+
76+
// 使用二分查找优化查找效率
77+
const findNearestIndex = (arr, target) => {
78+
let left = 0;
79+
let right = arr.length - 1;
80+
let result = 0;
81+
while (left <= right) {
82+
const mid = Math.floor((left + right) / 2);
83+
if (arr[mid] <= target + dynamicThreshold) {
84+
result = mid;
85+
left = mid + 1;
86+
} else {
87+
right = mid - 1;
88+
}
89+
}
90+
return result;
91+
};
7492

75-
const index = this.offsetTopList.findIndex((top) => top > scrollTop && top - scrollTop <= threshold);
93+
const newIndex = findNearestIndex(this.offsetTopList, scrollTop);
7694

77-
if (index > -1) {
78-
this.setData({ sideBarIndex: index });
95+
if (newIndex !== this.data.sideBarIndex) {
96+
this.setData({ sideBarIndex: newIndex });
7997
}
8098
},
8199
});

src/side-bar/_example/with-icon/index.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const items = new Array(12).fill().map((_, index) => ({
66

77
Page({
88
offsetTopList: [],
9+
lastScrollTop: 0,
910
data: {
1011
sideBarIndex: 1,
1112
scrollTop: 0,
@@ -71,16 +72,33 @@ Page({
7172
onScroll(e) {
7273
const { scrollTop } = e.detail;
7374
const threshold = 50; // 下一个标题与顶部的距离
75+
const direction = scrollTop > this.lastScrollTop ? 'down' : 'up';
76+
this.lastScrollTop = scrollTop;
7477

75-
if (scrollTop < threshold) {
76-
this.setData({ sideBarIndex: 0 });
77-
return;
78-
}
78+
// 动态调整阈值:向下滚动时增大阈值,向上时减小
79+
const dynamicThreshold = direction === 'down' ? threshold * 1.5 : threshold * 0.8;
80+
81+
// 使用二分查找优化查找效率
82+
const findNearestIndex = (arr, target) => {
83+
let left = 0;
84+
let right = arr.length - 1;
85+
let result = 0;
86+
while (left <= right) {
87+
const mid = Math.floor((left + right) / 2);
88+
if (arr[mid] <= target + dynamicThreshold) {
89+
result = mid;
90+
left = mid + 1;
91+
} else {
92+
right = mid - 1;
93+
}
94+
}
95+
return result;
96+
};
7997

80-
const index = this.offsetTopList.findIndex((top) => top > scrollTop && top - scrollTop <= threshold);
98+
const newIndex = findNearestIndex(this.offsetTopList, scrollTop);
8199

82-
if (index > -1) {
83-
this.setData({ sideBarIndex: index });
100+
if (newIndex !== this.data.sideBarIndex) {
101+
this.setData({ sideBarIndex: newIndex });
84102
}
85103
},
86104
});

0 commit comments

Comments
 (0)