发生 focusOut 事件时如何停用某个功能?

问题描述 投票:0回答:1

目标

我想要两个搜索栏,每个搜索栏都可以:

  • 输入时显示建议
  • 使用箭头键选择项目
  • 每件商品均可定制

因为最后一个项目符号,我不想使用

<datalist>
标签,因为它的样式有限。我还使用 Deno Fresh,它基于 Preact,Preact 又基于 React。当时我不知道通过箭头键导航列表的指南 在React中,但是在vanilla JS中,我认为使用vanilla版本会更简单,所以目前我正在使用它。

问题

当通过键盘导航一个列表时,另一个列表也会被触发。我的想法是让脚本针对不同的列表,当用户取消输入字段的焦点时,它将被停用。我尝试在脚本中添加这个:

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> <div className="search-bar-container"> <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> </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 仍然会出现孪生错误。这确实在我的机器上运行。
截图(GIF)

javascript react-hooks onblur focusout freshjs
1个回答
0
投票
您需要单独管理每个列表的活动状态。您可以添加状态变量来跟踪活动列表,然后根据活动列表有条件地执行导航逻辑。这是您修改后的代码:

import { useState } from "react"; export default function SearchBar() { const [keyword1, setKeyword1] = useState(""); const [keyword2, setKeyword2] = useState(""); const [activeList, setActiveList] = useState(null); // State to track active list 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']; const handleKeyDown = (e, list) => { if (e.key === "ArrowDown" || e.key === "ArrowUp") { e.preventDefault(); setActiveList(list); // Set active list } }; return ( <div className="search-bar-container"> <input type="text" placeholder={'Search list 1'} value={keyword1} onInput={(e) => { setKeyword1(e.target.value); setActiveList('1'); // Set active list }} onBlur={() => setActiveList(null)} // Deactivate list when input loses focus onKeyDown={(e) => handleKeyDown(e, '1')} // Pass list identifier to handleKeyDown /> <br /> <ul id={'Suggested list 1'} style={{ display: activeList === '1' ? 'block' : 'none' }}> {/* Conditionally render based on active list */} {keyword1 !== '' ? list1.filter(keyword => keyword.includes(keyword1)).map( (item, index) => <li key={index}>{item}</li>, ) : ''} </ul> <div> Your selected item is :<span id="Item 1"></span> </div> <div className="search-bar-container"> <input type="text" placeholder={'Search list 2'} value={keyword2} onInput={(e) => { setKeyword2(e.target.value); setActiveList('2'); // Set active list }} onBlur={() => setActiveList(null)} // Deactivate list when input loses focus onKeyDown={(e) => handleKeyDown(e, '2')} // Pass list identifier to handleKeyDown /> <br /> <ul id={'Suggested list 2'} style={{ display: activeList === '2' ? 'block' : 'none' }}> {/* Conditionally render based on active list */} {keyword2 !== '' ? list2.filter(keyword => keyword.includes(keyword2)).map( (item, index) => <li key={index}>{item}</li>, ) : ''} </ul> <div> Your selected item is :<span id="Item 2"></span> </div> </div> </div> ); }
    
© www.soinside.com 2019 - 2024. All rights reserved.