我要做的是将密钥代码放在一个数组中,稍后再做一些有趣的事情。因此,我捕获击键,获取插入位置并将关键代码放入数组中(在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
事件中的数组中。没有不同。我想知道是否使用小暂停(即强制用户输入更慢)可能会解决它,但这感觉就像一个黑客,我宁愿一个'正确'的解决方案。希望有一个。
答案 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
作为额外的偏执检查,只要您不希望重建确切的输入。例如,您可以简单地检查释放的键是否与当前光标位置的字符匹配。但坦率地说,我不确定这是值得的。