SVELTE 中即时搜索和列表选择的几个问题
A couple of problems with instant search and list selection in SVELTE
我有下面的代码。预期行为如下:
- 当页面加载时,表单域应该处于焦点。
- 当用户单击 up/down 箭头时,应通过 CSS 背景颜色更改来选择列表中的项目。
- 当用户在表单字段中键入内容时,“即时搜索”将应用于列表,并且只会显示与搜索相匹配的项目。
- 如果用户键入了不在列表中的项目并提交了该项目,页面应自动更新以显示列表和列表中的新项目。
在第 4 步之前一切似乎都正常。如果您尝试将项目提交到列表,页面不会更新新项目并且表单失去焦点。
我之前使用 ref 和 useEffect 使用 React 创建了这个脚本。我正在探索 SVELTE 以查看类似脚本的外观。
谢谢!
交互示例:
https://svelte.dev/repl/a544e3d48d3f46c89249d16c10270f0f?version=3.30.0
<script>
import { onMount } from 'svelte';
let clients = ["a Little piggy","b little piggy","c little piggy"]; //hard coded api data
let clientsClone = [...clients];
let indexVal = -1;
let downArrowPress = 40;
let upArrowPress = 38;
let clientInputTextField = "";
let selectedClient = "";
//______________________BEGIN focus input field on page load
onMount(function() {
clientInputTextField.focus();
});
//_______________________END focus input field on page load.
// ______________________BEGIN instant search algorithm
function instantSearch(query,listArr) {
let arr = [...listArr]
let newList = []
arr.map(val =>{
query.split(" ").map(word =>{
if(val.toLowerCase().indexOf(word.toLowerCase()) != -1){
newList.push(val)
}
})
})
console.log(newList)
return newList
}
//_________________________END instant search algorithm
function handleKeydown(event){
if(event.keyCode === upArrowPress){
indexVal-=1;
indexVal = indexVal < 0 ? clients.length : indexVal
console.log(indexVal);
}
if(event.keyCode === downArrowPress){
indexVal+=1;
indexVal = indexVal > clients.length ? 0 : indexVal
console.log(indexVal);
}
if(indexVal > clients.length -1 || indexVal < 0){
clientInputTextField.focus();
}else{
clientInputTextField.blur()
}
}
function searchItems(event){
console.log(event.target.value)
let result = instantSearch(event.target.value, clients);
clientsClone = [...result]
console.log(result)
}
function handleSubmit(){
console.log(selectedClient)
clients.push(selectedClient)
selectedClient = "";
}
</script>
<svelte:window on:keydown={handleKeydown}/>
<form on:submit|preventDefault={handleSubmit}>
<input type="text" name="" on:input={searchItems} bind:this={clientInputTextField} bind:value={selectedClient}>
<input type="submit" name="">
</form>
<ul>
{#each clientsClone as client, i}
{#if i === indexVal}
<li style="background-color:orange">{client}</li>
{:else}
<li style="">{client}</li>
{/if}
{/each}
</ul>
编辑
“即时搜索”太乱了,我真的只有以下代码可以工作:
https://svelte.dev/repl/a52d1935209f4cbbb8289b0096374288?version=3.30.0
<script>
import { onMount } from 'svelte';
let clients = ["a Little piggy","b little piggy","c little piggy"];
let indexVal = -1;
let downArrowPress = 40;
let upArrowPress = 38;
let clientInputTextField = "";
onMount(function() {
clientInputTextField.focus();
});
function handleKeydown(event){
if(event.keyCode === upArrowPress){
indexVal-=1;
indexVal = indexVal < 0 ? clients.length : indexVal
console.log(indexVal);
}
if(event.keyCode === downArrowPress){
indexVal+=1;
indexVal = indexVal > clients.length ? 0 : indexVal
console.log(indexVal);
}
if(indexVal > clients.length -1 || indexVal < 0){
clientInputTextField.focus();
}else{
clientInputTextField.blur()
}
}
</script>
<svelte:window on:keydown={handleKeydown}/>
<form>
<input type="text" name="" bind:this={clientInputTextField} >
<input type="submit" name="">
</form>
<ul>
{#each clients as client, i}
{#if i === indexVal}
<li style="background-color:orange">{client}</li>
{:else}
<li style="">{client}</li>
{/if}
{/each}
</ul>
您需要将事件处理程序附加到侦听 submit
事件的表单。要获取 input
字段的值,您还需要为其提供 name
属性:
<form on:submit|preventDefault={handleSubmit}>
<input type="text" name="input" bind:this={clientInputTextField} >
<input type="submit" name="">
</form>
请注意,preventDefault
修饰符会阻止页面实际提交表单(即更改 URL)。根据您的用例,您可能不希望出现此行为。
然后更新您的 clients
列表,您可以像这样定义一个简单的 handleSubmit
函数:
function handleSubmit(e) {
const value = e.target.input.value;
clients = [...clients, value]
}
将此添加到您编辑的代码后,完整示例如下所示:
<script>
import { onMount } from 'svelte';
let clients = ["a Little piggy","b little piggy","c little piggy"];
let indexVal = -1;
let downArrowPress = 40;
let upArrowPress = 38;
let clientInputTextField = "";
onMount(function() {
clientInputTextField.focus();
});
function handleKeydown(event) {
if(event.keyCode === upArrowPress) {
indexVal-=1;
indexVal = indexVal < 0 ? clients.length : indexVal
console.log(indexVal);
}
if(event.keyCode === downArrowPress) {
indexVal+=1;
indexVal = indexVal > clients.length ? 0 : indexVal
console.log(indexVal);
}
if(indexVal > clients.length -1 || indexVal < 0){
clientInputTextField.focus();
} else {
clientInputTextField.blur()
}
}
function handleSubmit(e) {
const value = e.target.input.value;
console.log(value);
clients = [...clients, value]
}
</script>
<svelte:window on:keydown={handleKeydown}/>
<form on:submit|preventDefault={handleSubmit}>
<input type="text" name="input" bind:this={clientInputTextField} >
<input type="submit" name="">
</form>
<ul>
{#each clients as client, i}
{#if i === indexVal}
<li style="background-color:orange">{client}</li>
{:else}
<li style="">{client}</li>
{/if}
{/each}
</ul>
我有下面的代码。预期行为如下:
- 当页面加载时,表单域应该处于焦点。
- 当用户单击 up/down 箭头时,应通过 CSS 背景颜色更改来选择列表中的项目。
- 当用户在表单字段中键入内容时,“即时搜索”将应用于列表,并且只会显示与搜索相匹配的项目。
- 如果用户键入了不在列表中的项目并提交了该项目,页面应自动更新以显示列表和列表中的新项目。
在第 4 步之前一切似乎都正常。如果您尝试将项目提交到列表,页面不会更新新项目并且表单失去焦点。
我之前使用 ref 和 useEffect 使用 React 创建了这个脚本。我正在探索 SVELTE 以查看类似脚本的外观。
谢谢!
交互示例:
https://svelte.dev/repl/a544e3d48d3f46c89249d16c10270f0f?version=3.30.0
<script>
import { onMount } from 'svelte';
let clients = ["a Little piggy","b little piggy","c little piggy"]; //hard coded api data
let clientsClone = [...clients];
let indexVal = -1;
let downArrowPress = 40;
let upArrowPress = 38;
let clientInputTextField = "";
let selectedClient = "";
//______________________BEGIN focus input field on page load
onMount(function() {
clientInputTextField.focus();
});
//_______________________END focus input field on page load.
// ______________________BEGIN instant search algorithm
function instantSearch(query,listArr) {
let arr = [...listArr]
let newList = []
arr.map(val =>{
query.split(" ").map(word =>{
if(val.toLowerCase().indexOf(word.toLowerCase()) != -1){
newList.push(val)
}
})
})
console.log(newList)
return newList
}
//_________________________END instant search algorithm
function handleKeydown(event){
if(event.keyCode === upArrowPress){
indexVal-=1;
indexVal = indexVal < 0 ? clients.length : indexVal
console.log(indexVal);
}
if(event.keyCode === downArrowPress){
indexVal+=1;
indexVal = indexVal > clients.length ? 0 : indexVal
console.log(indexVal);
}
if(indexVal > clients.length -1 || indexVal < 0){
clientInputTextField.focus();
}else{
clientInputTextField.blur()
}
}
function searchItems(event){
console.log(event.target.value)
let result = instantSearch(event.target.value, clients);
clientsClone = [...result]
console.log(result)
}
function handleSubmit(){
console.log(selectedClient)
clients.push(selectedClient)
selectedClient = "";
}
</script>
<svelte:window on:keydown={handleKeydown}/>
<form on:submit|preventDefault={handleSubmit}>
<input type="text" name="" on:input={searchItems} bind:this={clientInputTextField} bind:value={selectedClient}>
<input type="submit" name="">
</form>
<ul>
{#each clientsClone as client, i}
{#if i === indexVal}
<li style="background-color:orange">{client}</li>
{:else}
<li style="">{client}</li>
{/if}
{/each}
</ul>
编辑
“即时搜索”太乱了,我真的只有以下代码可以工作:
https://svelte.dev/repl/a52d1935209f4cbbb8289b0096374288?version=3.30.0
<script>
import { onMount } from 'svelte';
let clients = ["a Little piggy","b little piggy","c little piggy"];
let indexVal = -1;
let downArrowPress = 40;
let upArrowPress = 38;
let clientInputTextField = "";
onMount(function() {
clientInputTextField.focus();
});
function handleKeydown(event){
if(event.keyCode === upArrowPress){
indexVal-=1;
indexVal = indexVal < 0 ? clients.length : indexVal
console.log(indexVal);
}
if(event.keyCode === downArrowPress){
indexVal+=1;
indexVal = indexVal > clients.length ? 0 : indexVal
console.log(indexVal);
}
if(indexVal > clients.length -1 || indexVal < 0){
clientInputTextField.focus();
}else{
clientInputTextField.blur()
}
}
</script>
<svelte:window on:keydown={handleKeydown}/>
<form>
<input type="text" name="" bind:this={clientInputTextField} >
<input type="submit" name="">
</form>
<ul>
{#each clients as client, i}
{#if i === indexVal}
<li style="background-color:orange">{client}</li>
{:else}
<li style="">{client}</li>
{/if}
{/each}
</ul>
您需要将事件处理程序附加到侦听 submit
事件的表单。要获取 input
字段的值,您还需要为其提供 name
属性:
<form on:submit|preventDefault={handleSubmit}>
<input type="text" name="input" bind:this={clientInputTextField} >
<input type="submit" name="">
</form>
请注意,preventDefault
修饰符会阻止页面实际提交表单(即更改 URL)。根据您的用例,您可能不希望出现此行为。
然后更新您的 clients
列表,您可以像这样定义一个简单的 handleSubmit
函数:
function handleSubmit(e) {
const value = e.target.input.value;
clients = [...clients, value]
}
将此添加到您编辑的代码后,完整示例如下所示:
<script>
import { onMount } from 'svelte';
let clients = ["a Little piggy","b little piggy","c little piggy"];
let indexVal = -1;
let downArrowPress = 40;
let upArrowPress = 38;
let clientInputTextField = "";
onMount(function() {
clientInputTextField.focus();
});
function handleKeydown(event) {
if(event.keyCode === upArrowPress) {
indexVal-=1;
indexVal = indexVal < 0 ? clients.length : indexVal
console.log(indexVal);
}
if(event.keyCode === downArrowPress) {
indexVal+=1;
indexVal = indexVal > clients.length ? 0 : indexVal
console.log(indexVal);
}
if(indexVal > clients.length -1 || indexVal < 0){
clientInputTextField.focus();
} else {
clientInputTextField.blur()
}
}
function handleSubmit(e) {
const value = e.target.input.value;
console.log(value);
clients = [...clients, value]
}
</script>
<svelte:window on:keydown={handleKeydown}/>
<form on:submit|preventDefault={handleSubmit}>
<input type="text" name="input" bind:this={clientInputTextField} >
<input type="submit" name="">
</form>
<ul>
{#each clients as client, i}
{#if i === indexVal}
<li style="background-color:orange">{client}</li>
{:else}
<li style="">{client}</li>
{/if}
{/each}
</ul>