diff --git a/src/components/VirtualList.vue b/src/components/VirtualList.vue index 0934acc..4684575 100644 --- a/src/components/VirtualList.vue +++ b/src/components/VirtualList.vue @@ -191,6 +191,10 @@ const lastReachBoundaryTime = ref<{ top: number; bottom: number }>({ bottom: 0 }) +// 添加新的状态变量用于追踪按键状��� +const isKeyPressed = ref(false) +let keyPressTimer: number | null = null + /** * 处理键盘事件 * 实现键盘导航、边界循环和项目选择功能 @@ -204,13 +208,25 @@ function handleKeyDown(e: KeyboardEvent): void { const item = props.data[selectedIndex.value] emit('click', { ...item, index: selectedIndex.value }) } - } else if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { + return + } + + if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { e.preventDefault() const isFirstItem = selectedIndex.value === 0 const isLastItem = selectedIndex.value === props.data.length - 1 const now = Date.now() + // 只在首尾项时检查按键状态 + if ((e.key === 'ArrowUp' && isFirstItem) || (e.key === 'ArrowDown' && isLastItem)) { + if (isKeyPressed.value) { + return + } + isKeyPressed.value = true + if (keyPressTimer) clearTimeout(keyPressTimer) + } + if (e.key === 'ArrowUp' && isFirstItem) { const timeSinceLastTop = now - lastReachBoundaryTime.value.top if (timeSinceLastTop < 5000) { @@ -247,6 +263,7 @@ function handleKeyDown(e: KeyboardEvent): void { return } + // 非首尾项的正常导航逻辑 isKeyboardNavigating.value = true if (keyboardTimer) clearTimeout(keyboardTimer) @@ -277,6 +294,17 @@ function handleKeyDown(e: KeyboardEvent): void { } } +// 添加键盘抬起事件处理函数 +function handleKeyUp(e: KeyboardEvent): void { + if (e.key === 'ArrowUp' || e.key === 'ArrowDown') { + // 设置一个短暂的延时,确保不会立即响应下一次按键 + if (keyPressTimer) clearTimeout(keyPressTimer) + keyPressTimer = window.setTimeout(() => { + isKeyPressed.value = false + }, 50) + } +} + /** * 保持选中项在可视区域内 * 如果选中项不可见,则滚动到合适位置 @@ -330,6 +358,7 @@ onMounted(() => { // 添加全局事件监听 window.addEventListener('resize', updateContainerHeight) window.addEventListener('keydown', handleKeyDown) + window.addEventListener('keyup', handleKeyUp) }) onBeforeUnmount(() => { @@ -344,8 +373,10 @@ onBeforeUnmount(() => { window.removeEventListener('resize', updateContainerHeight) window.removeEventListener('keydown', handleKeyDown) + window.removeEventListener('keyup', handleKeyUp) if (keyboardTimer) clearTimeout(keyboardTimer) if (hoverTimer) clearTimeout(hoverTimer) + if (keyPressTimer) clearTimeout(keyPressTimer) })