Browse Source

fix(home/book): 优化滚动检测阈值和位置计算逻辑

提高手动滚动检测阈值从50到80,减少误判
增加元素可视范围检查功能,优化滚动位置计算
统一精确滚动和普通滚动的阈值至30,减少不必要的微小滚动
main
前端-胡立永 21 hours ago
parent
commit
fb7c04ce44
1 changed files with 82 additions and 13 deletions
  1. +82
    -13
      subPages/home/book.vue

+ 82
- 13
subPages/home/book.vue View File

@ -373,9 +373,9 @@ export default {
if (Math.abs(previousScrollTop - scrollTop) > 5) {
//
if (this.isScrolling) {
//
//
const scrollDifference = Math.abs(previousScrollTop - scrollTop);
if (scrollDifference > 50) { //
if (scrollDifference > 80) { // 5080
console.log('🖐️ 检测到手动滚动,中断自动滚动状态');
this.isScrolling = false;
this.lastUserScrollTime = Date.now(); //
@ -841,7 +841,8 @@ export default {
const currentScroll = this.scrollTops[this.currentPage - 1] || 0;
const scrollDifference = Math.abs(preciseScrollTop - currentScroll);
if (scrollDifference > 20) {
//
if (scrollDifference > 30) { // 2030
this.$set(this.scrollTops, this.currentPage - 1, preciseScrollTop);
console.log('✅ 使用精确位置滚动:', {
selector,
@ -856,7 +857,7 @@ export default {
}, 200);
} else {
resetScrollingState();
console.log('📍 目标已在视野内,无需滚动');
console.log('📍 目标已在最佳可视位置,无需滚动');
}
} else {
// 使
@ -910,7 +911,8 @@ export default {
const currentScroll = this.scrollTops[this.currentPage - 1] || 0;
const scrollDifference = Math.abs(finalScrollTop - currentScroll);
if (scrollDifference > 20) { //
//
if (scrollDifference > 30) { // 2030
this.$set(this.scrollTops, this.currentPage - 1, finalScrollTop);
//
@ -928,7 +930,7 @@ export default {
} else {
//
resetScrollingState();
console.log('📍 目标已在视野内,无需滚动');
console.log('📍 目标已在最佳可视位置,无需滚动');
}
} else {
console.error('❌ 未找到目标元素或scroll-view:', {
@ -1035,6 +1037,75 @@ export default {
});
},
//
isElementInViewport(elementPosition, currentScrollTop) {
const screenHeight = uni.getSystemInfoSync().windowHeight;
const viewportTop = currentScrollTop;
const viewportBottom = currentScrollTop + screenHeight;
//
const elementTop = elementPosition.top;
const elementBottom = elementPosition.bottom;
//
const isVisible = elementBottom > viewportTop && elementTop < viewportBottom;
//
const visibleTop = Math.max(elementTop, viewportTop);
const visibleBottom = Math.min(elementBottom, viewportBottom);
const visibleHeight = Math.max(0, visibleBottom - visibleTop);
const visibilityRatio = visibleHeight / elementPosition.height;
return {
isVisible,
visibilityRatio,
elementTop,
elementBottom,
viewportTop,
viewportBottom
};
},
//
calculateOptimalScrollPosition(targetElement, currentScrollTop) {
const screenHeight = uni.getSystemInfoSync().windowHeight;
//
const visibility = this.isElementInViewport(targetElement, currentScrollTop);
//
if (visibility.isVisible && visibility.visibilityRatio > 0.8) {
// 1/32/3
const elementCenter = (targetElement.top + targetElement.bottom) / 2;
const relativePosition = (elementCenter - currentScrollTop) / screenHeight;
if (relativePosition >= 0.2 && relativePosition <= 0.7) {
console.log('📍 元素已在最佳可视位置,无需滚动');
return null; //
}
}
// 1/3
const optimalOffsetRatio = 0.3; // 30%1/4
const offsetFromTop = screenHeight * optimalOffsetRatio;
//
const elementHeight = targetElement.height;
const adjustedOffset = Math.min(offsetFromTop, screenHeight * 0.1); // 10%
const targetScrollTop = Math.max(0, targetElement.top - adjustedOffset);
console.log('🎯 计算最佳滚动位置:', {
currentVisibility: visibility,
elementHeight,
optimalOffsetRatio,
adjustedOffset,
targetScrollTop
});
return targetScrollTop;
},
//
async calculatePreciseScrollPosition(scrollData, elementPositions) {
if (!elementPositions || elementPositions.length === 0) {
@ -1063,18 +1134,16 @@ export default {
return null;
}
// 1/4
const screenHeight = uni.getSystemInfoSync().windowHeight;
const offsetFromTop = screenHeight * 0.25;
//
const currentScrollTop = this.scrollTops[this.currentPage - 1] || 0;
// = -
const targetScrollTop = Math.max(0, targetElement.top - offsetFromTop);
// 使
const targetScrollTop = this.calculateOptimalScrollPosition(targetElement, currentScrollTop);
console.log('🎯 精确滚动位置计算:', {
targetElementIndex,
targetElement,
screenHeight,
offsetFromTop,
currentScrollTop,
targetScrollTop
});


Loading…
Cancel
Save