如何在focusOut事件触发时停用搜索框的键盘导航功能?
目标
我需要实现两个搜索框,每个需具备以下功能:
- 输入时显示建议列表
- 通过方向键选择列表项
- 列表项样式可自定义
由于最后一点需求,我不想使用<datalist>标签(其样式受限)。我使用的是基于Preact(Preact基于React)的Deno Fresh框架。当时未找到React中方向键导航列表的相关指南,仅找到原生JS的实现方案,因此选择使用原生JS来开发。
若你关注整体目标的实现而非当前问题,我已经整理了对应的最终解决方案。
问题
当用键盘导航其中一个搜索框的建议列表时,另一个搜索框的列表也会被触发。我的思路是让脚本分别定位不同列表,并在输入框失去焦点时停用对应功能。我在脚本中添加了:
if (list === 'deactivate') return
并在每个输入框的事件处理器中添加:
onBlur={(e) => script('deactivate')}
但该方案无效,请问有什么解决建议?
代码
search.jsx:
export default function SearchBar() { const [keyword1, setKeyword1] = useState(""); const [keyword2, setKeyword2] = useState(""); const list1 = [ 'rabbits', 'raccoons', 'reindeer', 'red pandas', 'rhinoceroses', 'river otters', 'rattlesnakes', 'roosters' ] const list2 = [ 'jacaranda', 'jacarta', 'jack-o-lantern orange', 'jackpot', 'jade', 'jade green', 'jade rosin', 'jaffa' ] return ( <div className="search-bar-container"> <input type="text" placeholder={'Search list 1'} value={keyword1} onInput={(e) => { setKeyword1(e.target.value); script('1'); }} onBlur={(e) => script('deactivate')} /> <br /> <ul id={'Suggested list 1'}> {keyword1 !== '' ? list1.filter(keyword => keyword.includes(keyword1)).map( (item) => <li>{item}</li>, ) : ''} </ul> <div> Your selected item is :<span id="Item 1"></span> </div> <input type="text" placeholder={'Search list 2'} value={keyword2} onInput={(e) => { setKeyword2(e.target.value); script('2'); }} onBlur={(e) => script('deactivate') } /> <br /> <ul id={'Suggested list 2'}> {keyword2 !== '' ? list2.filter(keyword => keyword.includes(keyword2)).map( (item) => <li>{item}</li>, ): ''} </ul> <div> Your selected item is :<span id="Item 2"></span> </div> </div> ); }
script.ts:
export function script(list: "1" | "2" | 'deactivate') { if (list === 'deactivate') return if (window !== undefined) { const ul = document.getElementById(`Suggested list ${list}`); const result = document.getElementById(`Item ${list}`); //the rest of the script
完整代码可参考本地运行版本(CodeSandbox存在twind错误,本地运行正常)。

内容的提问来源于stack exchange,提问作者Ooker
相关产品推荐
相关产品推荐

