优化列表边界触发对齐的效果
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user