我一直在尝试使用键盘导航来构建可以手动排序的项目列表。使用步骤如下:
问题是,根据我放置物品的位置,我会得到不同的行为。如果我将其下降一位,一切都会按预期运行,但如果我将其上升一位或下降两位或更多位,焦点就会丢失。我已经尝试调试它好几天了,但我仍然无法判断这是我忽略了 Svelte 反应系统的东西还是仅仅与浏览器中的焦点处理有关。不管怎样,我得到的结果不一致,这真的让我很困惑。
您可以在此 REPL 中进行测试:https://svelte.dev/repl/2fbb34a7283e417ea995d674946a991a?version=4.2.12
值得一提的是,我知道每个浏览器管理焦点的方式略有不同(特别是在失去焦点时),并且这种情况仅发生在 Chromium 浏览器中,而不是在 Firefox 或 Safari 中,我在这些浏览器中获得了一致的结果(有在 Windows 和 MacOS 中进行了测试)。
如果我从#each循环中删除密钥(从
{#each items as item, index (item.id)}
到{#each items as item, index}
),它在Chromium浏览器中也开始表现一致,但这不是一个好的做法,不应该是必要的,它导致我正如您想象的那样,有不同类型的问题。
感谢 James 的评论指出了 Svelte 存储库中的特定 问题,我能够找到解决我的问题的方法。
Svelte(至少在 v4 中)似乎在移动元素时(即使为它们分配了正确的键)不会保留焦点,因此有必要在更新后手动将焦点保持在相应的元素上。
基本上,我们可以在每次更新时重新聚焦活动元素:
import { beforeUpdate, afterUpdate } from 'svelte'
let activeElement: HTMLElement;
beforeUpdate(() => {
activeElement = document?.activeElement as HTMLElement;
});
afterUpdate(() => {
if (activeElement) activeElement.focus();
});
这是一个新的 REPL,其中包含上述更改:解决方案 REPL。