问题描述
我想制作自定义的 4 位代码输入组件。 顺便说一下,当按键更快时避免异常动作我希望在更新值后将焦点设置在按键动作的其他元素上。但它不起作用。
<script>
let value:string[] = new Array(4).fill("")
let elemIdx:number = 0;
function handleChange(event: any,element: number): void {
elemIdx = element;
value[element] = event.target.value;
}
afterUpdate(() => {
if (elemIdx < 3) {
input[elemIdx + 1].focus();
}
});
</script>
<input
bind:this={input[i]}
on:keypress={(e) => handleChange(e,i)}
autocomplete="off"
/>
解决方法
我会在您的代码中更改一些内容:
- 改用
on:input
事件,每当值改变时都会触发 - 使用
nexElementSibling
来识别下一个输入
这将大大简化您的代码:
<script>
const value = new Array(4).fill("")
const handleInput = (ev,i) => i < value.length - 1 && ev.target.nextSibling.focus()
</script>
{#each value as v,i}
<input bind:value={v} autocomplete="off" maxlength="1"
on:input={(ev) => handleInput(ev,i)}
/>
{/each}
要了解我们这里有什么:
- 我们从一个 4 元素的空格数组开始
- 我们遍历这个数组,将每个输入绑定到数组中的相应位置,这将使数组与输入元素保持同步
- 当输入元素的值发生变化时,我们会触发一个函数来获取当前输入元素及其索引
- 此函数将元素的索引与值数组的长度进行比较,如果不在末尾,则查看下一个元素并将焦点设置在该元素上。
作为奖励,每个输入都会获得 maxlength="1"
,这将防止用户输入多个字符。
另一个好处是,这完全取决于您需要多少个字符,如果您想要 10 个字符,只需创建一个包含 10 个项目的数组即可。