插入位置不跟踪?

时间:2012-05-09 08:15:17

标签: javascript javascript-events mootools

我要做的是将密钥代码放在一个数组中,稍后再做一些有趣的事情。因此,我捕获击键,获取插入位置并将关键代码放入数组中(在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事件中的数组中。没有不同。我想知道是否使用小暂停(即强制用户输入更慢)可能会解决它,但这感觉就像一个黑客,我宁愿一个'正确'的解决方案。希望有一个。

3 个答案:

答案 0 :(得分:0)

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

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

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

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

你可以使用一个对象,虽然在所有浏览器中vs按键的顺序都没有保证 - 特别是webkit,他们倾向于重新排序并将数字键放在对象键循环的顶部......但如果你像“pos”+ caretIndex这样的密钥前缀,你应该得到FIFO

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

例如。

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

使用对象,您可以这样做:

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

答案 1 :(得分:0)

经过多次测试后,它似乎是keyup特有的行为。当我使用keydown时,我获得一致的序列:http://jsfiddle.net/HQVR8/3/

一个缺点是keydown在我正在进行“价值收集”时落后于keyup,但在我的环境中,这只是一个小问题。

行为上的差异对我来说很奇怪:当你一次按下四个键时,keyup会为所有这些键显示相同的插入符号位置,而keydown显示四个不同的插入符号位置。这看起来很奇怪,因为你立即按下它们,但也立刻压下它们,所以插入符号'读数'应该是相同的。

答案 2 :(得分:0)

转到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事件。

我认为检测填充场的机器人并不是那么可靠(毕竟,一个合法的用户也可能想要粘贴密码),而且你不必担心像退格或任何其他非控制键那样-keyboard意味着清除输入。

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