插入符号位置未跟踪

Caret position not keeping track?

本文关键字:跟踪 位置 符号 插入      更新时间:2023-09-26

我想做的是将键码放在一个数组中,以便稍后做一些有趣的事情。因此,我捕获击键,获取插入符号位置并将键代码放入数组中(在MooTools的帮助下(:

var keyArray = [];
$('form').addEvent('keyup', function(event) {
    var pos = document.activeElement.getCaretPosition();
    keyArray[pos] = event.code;
});

一般来说,这很好用。但是,在控制台中显示完整数组时,我注意到数组中有一些undefined值。进一步探索这一点,我发现快速打字时,插入符号位置似乎失去了轨道,或者响应速度快/慢。我做了一个jsfiddle来证明这一点:http://jsfiddle.net/HQVR8/1/

如果在此示例中快速键入,您将看到一个插入符号位置序列,例如

- 1 - 2 - 3 - 5 - 6 - 6.

但是当打字缓慢时,它是

- 1 - 2 - 3 - 4 - 5 - 6. 

当然,现在快速键入时的麻烦是我的数组中有一个undefined值并且我覆盖了一个数组项目。所以结果是不同的。

我的问题是我是否可以以某种方式让插入符号位置保持跟踪。我尝试使用"本机"selectionStart,但结果是一样的。我还尝试在keydown事件中捕获插入符号位置,并将其放入keyup事件中的数组中。没有区别。我想知道使用小停顿(即强迫用户打得更慢(是否可以解决它,但这感觉像是一个黑客,我更喜欢一个"适当"的解决方案。希望有一个。

你基本上是通过使用数组而不是对象来弄得一团糟。

数组索引很狡猾,如果你不小心,可能会创建sparse arrays。 例如:

var foo = [];
foo[0] = "one!"; // foo.length = 1;
foo[2] = "two!"; // foo.length = 3, foo[1] = undefined

因此,如果您键入太快并跳过返回值,它可能就是这样做的。 此外,粘贴等可以将插入符号进一步向下推......

您可能可以使用一个对象,尽管无法保证所有浏览器中键的顺序 - 尤其是 WebKit,他们倾向于重新排序并将数字键放在对象键循环的顶部......但是如果你像"pos"+caretIndex这样的键前缀,你应该得到FIFO

解决您提取没有未定义的实际代码的需求的一种方法是通过 Array.filter。

例如。

retArray = Array.filter(retArray, function(el) {
    return el !== undefined;
});

使用对象,您可以执行以下操作:

console.log(Object.values(foo));

经过更多的测试,它似乎是特定于keyup的行为。当我使用keydown时,我确实得到了一个一致的序列:http://jsfiddle.net/HQVR8/3/

一个缺点是,当你做我正在做的"价值收集"时,keydownkeyup落后一步,但在我的设置中,这只是一个小问题。

行为上的差异对我来说似乎很奇怪:当您一次按四个键时,keyup显示所有键的插入符号位置,而keydown显示四个单独的插入符号位置。这似乎很奇怪,因为您一次按下它们,但也一次按下它们,因此插入符号"读数"应该是相同的。

转到JSfiddle并摆弄这个:

a( 按下"Q",然后按下"W",然后释放">

Q",然后释放"W"(足够快以避免自动重复(。当您用多个手指:)"快速"键入时,这种顺序经常发生。

b( 让任何键按下足够长的时间,以便自动重复开始。

差异显而易见

基本上,keyUp在释放物理密钥时触发,但是

  • 在释放前一个键之前,可以按下另一个键
  • keyDown在自动重复的情况下被调用,而keyUp则不是

由于 carret 位置和任何文本区域更新都与 keyDown 保持同步,因此在监视keyUp时,您只会错过中间步骤。

在情况 (a( 中,keyUp处理程序看到 carret pos 从 0 跳到 2,因为释放"q"是因为在释放第一个键之前键入了两个字符。释放"w"不会改变carret位置,因此处理程序最终将q和w存储在位置2。

在情况 (b( 中,处理程序完全错过重复,并且仅存储密钥的最后一个实例。

作为结论,使用KeyUp永远不会达到预期的含义。

keyDown可以,但就个人而言,我宁愿钩住changed事件。

我认为检测填充字段的机器人同样可靠(毕竟,合法用户也可能想要粘贴密码(,并且您不必为退格键或任何其他非键盘清除输入方式等控制键而烦恼。

您可以使用keyUp作为额外的偏执检查,只要您不希望重建确切的输入。例如,您可以简单地检查释放的键是否与当前光标位置的字符匹配。但坦率地说,我不确定这是否值得费心。