优化首尾跳转的响应逻辑,当方向键一直按住的时候不触发跳转直到再点一次
This commit is contained in:
@@ -191,6 +191,10 @@ const lastReachBoundaryTime = ref<{ top: number; bottom: number }>({
|
||||
bottom: 0
|
||||
})
|
||||
|
||||
// 添加新的状态变量用于追踪按键状<E994AE><E78AB6><EFBFBD>
|
||||
const isKeyPressed = ref<boolean>(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)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user