如何专注于 Svelte 中新增的输入?

Posted

技术标签:

【中文标题】如何专注于 Svelte 中新增的输入?【英文标题】:How to focus on newly added inputs in 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>

【问题讨论】:

【参考方案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 后面,所以它还不存在。

以上是关于如何专注于 Svelte 中新增的输入?的主要内容,如果未能解决你的问题,请参考以下文章

jQuery:如何专注于输入文本字段,使光标位于文本的末尾?

更改编辑模式Vue.js + Typescript后如何专注于输入字段

如何专注于 EditText

如何专注于 vuejs 中的 v-for 中的输入

专注于下一个输入不起作用以及当用户在最后一个输入字段时如何提交表单

如何专注于在返回 false 不起作用的 js 中的第一个错误输入