如何使用方向键在卡片元素间导航并解决.next is not a function报错
问题根因
你触发报错的核心原因有两个:
- 你代码里写的
".card:focus"是普通字符串,不是DOM元素实例,自然没有next()、prev()方法,这两个方法本身也是jQuery的API,原生JS没有对应的同名方法。 - Lit组件默认开启Shadow DOM,直接用
document.querySelector('.card')是找不到Shadow DOM内部的元素的,需要先拿到自定义元素实例再访问其shadowRoot。
修复步骤
1. 修改子组件,让卡片可聚焦
给卡片div添加tabindex="0"属性,使其支持键盘聚焦,同时可以添加聚焦状态样式优化体验:
// 子组件样式部分新增:focus状态 .card:focus { outline: 3px solid #4f46e5; outline-offset: 2px; } // render部分修改div render() { const { name, image } = this; return html` <div class="card" tabindex="0"> <p>${name}</p> <img src=${image} /> </div> `; }
2. 修改父组件的键盘监听逻辑
调整事件绑定逻辑,补全元素获取、边界处理和事件清理逻辑:
useEffect(() => { const handleKeydown = (e) => { if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return; // 先拿到所有卡片元素 const allCardWrappers = Array.from(document.querySelectorAll('pokemon-card')); const allCards = allCardWrappers.map(wrapper => wrapper.shadowRoot.querySelector('.card')); if (allCards.length === 0) return; // 找到当前聚焦的卡片下标 const currentIndex = allCards.findIndex(card => card === document.activeElement?.shadowRoot?.activeElement); let targetIndex; if (currentIndex === -1) { // 没有卡片聚焦时默认选中第一个 targetIndex = 0; } else if (e.key === 'ArrowRight') { // 右方向键:到最后一个就切回第一个 targetIndex = currentIndex + 1 >= allCards.length ? 0 : currentIndex + 1; } else { // 左方向键:到第一个就切回最后一个 targetIndex = currentIndex - 1 < 0 ? allCards.length - 1 : currentIndex - 1; } allCards[targetIndex].focus(); e.preventDefault(); }; document.addEventListener('keydown', handleKeydown); // 组件卸载时移除监听,避免内存泄漏 return () => document.removeEventListener('keydown', handleKeydown); }, []); // 空依赖数组,仅在组件挂载时绑定一次
内容的提问来源于stack exchange,提问作者coding1223322
相关产品推荐
相关产品推荐

