更新后如何在 svelte 中放置焦点?

How to put focus after update in svelte?

我想制作自定义 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}

了解我们这里的内容:

  1. 我们从一个 4 元素的空格数组开始
  2. 我们遍历这个数组,将每个输入绑定到数组中的相应位置,这将使数组与输入元素保持同步
  3. 当输入元素的值发生变化时,我们会触发一个函数,该函数接受当前输入元素及其索引
  4. 此函数将元素的索引与值数组的长度进行比较,如果不在末尾,则查看下一个元素并将焦点设置在该元素上。

作为奖励,每个输入都会得到 maxlength="1",这将防止用户输入多个字符。 另一个好处是,这完全取决于您需要多少个字符,如果您想要 10 个字符,只需创建一个包含 10 个项目的数组即可。