【问题标题】:How to focus on newly added inputs in Svelte?如何专注于 Svelte 中新增的输入?
【发布时间】:2019-12-07 00:14:13
【问题描述】:

我使用#each 为tasks 数组的每个成员显示一个输入。当我单击“添加任务”按钮时,一个新元素被插入到数组中,因此#each 循环中出现了一个新输入。

如何在单击“添加任务”按钮时关注已添加的输入?

<script>
  let tasks = [];

  function addTask() {
    tasks = [...tasks, { title: "" }];
  }
</script>

{#each tasks as task}
  <input type="text" bind:value={task.title} />
{/each}

<button on:click={addTask}>Add task</button>

【问题讨论】:

    标签: javascript svelte


    【解决方案1】:

    Rich Harris 有一个更好的solution


    你可以使用use:action:

    动作是在创建元素时调用的函数。

    例如:

    <script>
      let tasks = [];
    
      function addTask() {
        tasks = [...tasks, { title: "" }];
      }
    
      function init(el){
        el.focus()
      }
    </script>
    
    {#each tasks as task}
      <input type="text" bind:value={task.title} use:init />
    {/each}
    
    <button on:click={addTask}>Add task</button>
    

    【讨论】:

    • @AntonZotov Rich Harris 有一个更好的解决方案并不奇怪
    • 你的也不错。我使用它是因为我在使用自动对焦时遇到了一些问题。我没有调查它,但它可能与这个 chrome 错误有关:当 URL 包含 Chrome 79 中的片段时自动对焦不起作用:bugs.chromium.org/p/chromium/issues/detail?id=1046357
    • autofocus 现在不推荐了; Svelte 语言工具不鼓励它。使用属性绝对是更优雅的解决方案,但这是无警告的!
    • 据我所知,对于 a11y,此解决方案并不比 Rich Harris 解决方案更好。它只是绕过了 Svelte 警告。它在愚弄 Svelte;但它不应该愚弄我们!
    【解决方案2】:

    你可以使用autofocus属性:

    <script>
      let tasks = [];
    
      function addTask() {
        tasks = [...tasks, { title: "" }];
      }
    </script>
    
    {#each tasks as task}
      <input type="text" bind:value={task.title} autofocus />
    {/each}
    
    <button on:click={addTask}>Add task</button>
    

    请注意,您会收到可访问性警告。那是因为accessibility guidelines 实际上建议你不要这样做:

    盲人或视力低下的人在未经许可移动焦点时可能会迷失方向。此外,自动对焦对于有运动控制障碍的人来说可能是个问题,因为它可能会为他们从自动对焦区域导航到页面/视图上的其他位置产生额外的工作。

    由您决定此建议是否与您的情况相关!

    【讨论】:

    • 建议的答案都不适用于我的情况;我会解释一下:我有一个带有 2 个输入的表单,提交表单后,我想让光标回到第一个输入中。有什么建议应该怎么做?谢谢!
    • 使用&lt;input bind:this={myInput}&gt; 获取您想要关注的输入的引用,然后在提交表单后调用myInput.focus()
    • 谢谢,这是一个很好的解决方案!然而,我渴望更多:不仅在提交之后,而且在提交之前。注:解决方案是使用自动对焦!
    • 如果自动对焦发生在页面加载阶段,您还会认为这是一个可访问性问题吗?例如:用户点击“登录”链接,引导他进入登录页面,登录页面被加载,“用户名”输入字段自动获得焦点。当您处于单应用应用程序模式时,它会有所不同吗?
    【解决方案3】:

    您可以使用bind:thistick

    例如:

    <script>
      import { tick } from 'svelte';
    
      let tasks = [];
    
      async function addTask() {
        let newTask = { title: "" };
        tasks = [...tasks, newTask];
    
        await tick();
        newTask.input.focus();
      }
    </script>
    
    {#each tasks as task}
      <input type="text" bind:value={task.title} bind:this={task.input} />
    {/each}
    
    <button on:click={addTask}>Add task</button>
    

    解释我的方法的优点

    如果tasks 数组最初不是空的会怎样? 然后方法autofocususe:action 的缺点是当列表最初显示时,焦点在最后一个字段上。这可能是不可取的。

    我的方法仅在单击“添加”按钮时控制焦点。

    【讨论】:

    • Tick 是我的应用所需要的,因为该元素之前隐藏在 {#if} 后面,所以它还不存在。
    猜你喜欢
    • 2017-04-09
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多