优化列表边界触发对齐的效果

This commit is contained in:
2024-12-11 12:43:12 +08:00
parent 21e617bbd6
commit 40aafef83f

View File

@@ -125,6 +125,7 @@ const handleScroll = debounce(() => {
function handleMouseEnter(index) {
if (!isKeyboardNavigating.value) {
selectedIndex.value = index
// 移除滚动检查和处理,直接调用确保可见的方法
ensureSelectedItemVisible()
}
}
@@ -138,23 +139,29 @@ function handleKeyDown(e) {
if (keyboardTimer) clearTimeout(keyboardTimer)
const containerTop = containerRef.value.scrollTop
const currentVisibleStartIndex = Math.floor(containerTop / totalItemHeight.value)
const currentVisibleEndIndex = currentVisibleStartIndex + visibleCount.value - 1
const containerHeight = containerRef.value.clientHeight
if (e.key === 'ArrowUp') {
const nextIndex = Math.max(0, selectedIndex.value - 1)
if (nextIndex <= currentVisibleStartIndex) {
containerRef.value.scrollTop = nextIndex * totalItemHeight.value
}
selectedIndex.value = nextIndex
// 使用与向下相同的逻辑,计算项目顶部位置
const itemTop = nextIndex * totalItemHeight.value
if (itemTop < containerTop) {
containerRef.value.scrollTop = itemTop
}
} else {
const nextIndex = Math.min(props.data.length - 1, selectedIndex.value + 1)
if (nextIndex > currentVisibleEndIndex) {
containerRef.value.scrollTop = (nextIndex - visibleCount.value + 1) * totalItemHeight.value
}
selectedIndex.value = nextIndex
// 计算项目底部位置
const itemBottom = (nextIndex + 1) * totalItemHeight.value
const scrollBottom = containerTop + containerHeight
if (itemBottom > scrollBottom) {
containerRef.value.scrollTop = itemBottom - containerHeight
}
}
keyboardTimer = setTimeout(() => {
@@ -169,15 +176,18 @@ function ensureSelectedItemVisible() {
const containerTop = containerRef.value.scrollTop
const containerHeight = containerRef.value.clientHeight
const visibleCount = Math.floor(containerHeight / totalItemHeight.value)
const currentVisibleStartIndex = Math.floor(containerTop / totalItemHeight.value)
const currentVisibleEndIndex = currentVisibleStartIndex + visibleCount - 1
// 计算项目的顶部和底部位置
const itemTop = selectedIndex.value * totalItemHeight.value
const itemBottom = (selectedIndex.value + 1) * totalItemHeight.value
const scrollBottom = containerTop + containerHeight
if (selectedIndex.value < currentVisibleStartIndex) {
containerRef.value.scrollTop = selectedIndex.value * totalItemHeight.value
} else if (selectedIndex.value > currentVisibleEndIndex) {
containerRef.value.scrollTop = (selectedIndex.value - visibleCount + 1) * totalItemHeight.value
if (itemTop < containerTop) {
// 如果项目顶部超出可视区域,滚动到顶部对齐
containerRef.value.scrollTop = itemTop
} else if (itemBottom > scrollBottom) {
// 如果项目底部超出可视区域,滚动到底部对齐
containerRef.value.scrollTop = itemBottom - containerHeight
}
}