我想要两个搜索栏,每个搜索栏都可以:
<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)
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>
);
}