2

私がやろうとしているのは、キーコードを配列に入れて、後で面白いことをすることです。それで、私はキーストロークをキャプチャし、カレットの位置を取得し、キーコードを配列に配置します(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、配列に値があり、1つの配列項目を上書きすることです。したがって、結果は異なります。

私の質問は、どういうわけかカレットの位置を追跡させることができるかどうかです。selectionStart代わりに「ネイティブ」を使用してみましたが、結果は同じです。また、イベントでキャレットの位置をキャプチャし、keydownそれをイベントの配列に配置してみkeyupました。変わりはない。少し休止する(つまり、ユーザーにゆっくりと入力させる)ことで解決できるかどうか疑問に思っていますが、これはハックのように感じられるので、「適切な」解決策をお勧めします。うまくいけば、1つあります。

4

3 に答える 3

0

基本的に、オブジェクトの代わりに配列を使用して混乱を引き起こしています。

配列インデックスは危険であり、sparse arrays注意しないと作成される可能性があります。例えば:

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

したがって、入力が速すぎて戻り値をスキップした場合は、おそらくそれを実行しているだけです。また、貼り付けなどでカレットをさらに押し下げることができます...

すべてのブラウザでキーインとキーアウトの順序は保証されていませんが、おそらくオブジェクトを使用できます。特にWebkitは、オブジェクトのキーループの先頭に数値キーを並べ替えて配置する傾向があります...ただし、キーのプレフィックスを付けると「pos」+caretIndexのように、FIFOを取得する必要があります

未定義のコードなしで実際のコードを抽出する必要性を解決する1つの方法は、Array.filterを使用することです。

例えば。

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

オブジェクトを使用すると、次のことができます。

console.log(Object.values(foo));
于 2012-05-09T13:04:53.807 に答える
0

JSfiddle に移動して、これをいじります。

a) 'q' を押し、次に 'w' を押し、次に 'q' を放し、次に 'w' を放します (自動繰り返しを回避するのに十分な速さで)。この種のシーケンスは、複数の指で「すばやく」入力するときに非常に頻繁に発生します:)。

b) オートリピートが作動するのに十分な長さのキーを押したままにします。

違いは一目瞭然

基本的keyUpには物理キーを離すと発火しますが、

  • 前のキーが離される前に、別のキーを押すことができます
  • keyDown自動繰り返しの場合に呼び出されますが、そうでkeyUpはありません

キャレットの位置とテキスト領域の更新は と同期しているkeyDownため、監視中に中間ステップを見逃すだけですkeyUp

(a) の場合keyUp、最初のキーが離される前に 2 つの文字が入力されているため、'q' が離されると、ハンドラーはキャレット位置が 0 から 2 にジャンプすることを確認します。'w' を離してもキャレットの位置は変わらないため、ハンドラーは q と w の両方を位置 2 に格納することになります。

(b) の場合、ハンドラーは繰り返しを完全に見逃し、キーの最後のインスタンスのみを保存します。

結論として、使用してKeyUpも意図した意味は得られません。

keyDownchangedできますが、個人的にはイベントをフックしたいと思います。

フィールドに入力しているボットを検出することはそれほど信頼性が高くないと思います (結局のところ、正当なユーザーもパスワードを貼り付けたいと思う可能性があります)。入力をクリアします。

keyUp正確な入力を再構築することを期待しない限り、追加の偏執的なチェックとして使用できます。たとえば、リリースされたキーが現在のカーソル位置の文字と一致することを簡単に確認できます。しかし、率直に言って、わざわざする価値があるかどうかはわかりません。

于 2013-12-29T23:30:44.620 に答える
0

さらにいくつかのテストを行った結果、これは に固有の動作であると思われますkeyupkeydown私が使用すると、一貫したシーケンスが得られます: http://jsfiddle.net/HQVR8/3/

欠点の 1 つは、私が行っている「値の収集」を行っているときにkeydown一歩遅れることですが、私の設定では、これは小さな問題にすぎません。keyup

動作の違いは奇妙に思えます。一度に 4 つのキーを押すと、keyupはすべてのキーに対して同じキャレット位置を表示しますが、keydownは 4 つの別々のキャレット位置を表示します。一度に押すだけでなく、同時に押すので、これは奇妙に思えます。したがって、キャレットの「読み取り値」は同じでなければなりません。

于 2012-05-09T13:43:55.723 に答える