2016-05-19 4 views
0

それぞれの文字を別々のhtml入力に入力するPIN入力フォームが必要です。keyupイベントハンドラがフォーカスを変更してすぐに入力できない

javascriptでkeyupイベントをキャプチャしようとしているため、次の入力要素にフォーカスを変更して、マウスクリックやタブでユーザー自身で変更する必要がなくなりました。

ユーザーが本当にすばやく入力しない限り機能しています。例えば、ユーザーが本当にすばやく文字 '1'と '2'を入力すると、最初の入力に文字 '1'が正しく表示され、2番目の入力はまだ空で、フォーカスは3番目に移動しています入力。

なぜですか?

$(document).ready(function() { 
 

 
      $('.pinchar').keyup(function (e) { 
 
\t \t \t \t 
 
       if (
 
        (e.which == 8) //backspace 
 
        || (e.which == 46) // del 
 
        || (e.which == 9) // tab 
 
        || (e.which == 13) // return 
 
        || (e.which == 27) // esc 
 
        || (e.which == 37) // arrow 
 
        || (e.which == 38) // arrow 
 
        || (e.which == 39) // arrow 
 
        || (e.which == 40) // arrow 
 
        || (e.which == 27) // esc 
 
        || (e.which == 20) // CAPS LOCK 
 
        || (e.which == 17) // Ctrl 
 
        || (e.which == 18) // Alt 
 
        || (e.which == 16)) { //shift 
 

 
        return false; 
 
       } else { 
 
        $(this).parent().next().find('.pinchar').focus(); 
 
       } 
 
      }); 
 
    
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<table class="enterPINTable"> 
 
     <tr> 
 
     <td> 
 
      <input name="txtPIN1" id="txtPIN1" class="pinchar" size="1"> 
 
     </td> 
 
     <td> 
 
      <input name="txtPIN2" id="txtPIN2" class="pinchar" size="1"> 
 
     </td> 
 
     <td> 
 
      <input name="txtPIN3" id="txtPIN3" class="pinchar" size="1"> 
 
     </td> 
 
     <td> 
 
      <input name="txtPIN4" id="txtPIN4" class="pinchar" size="1"> 
 
     </td> 
 
     </tr> 
 
    </table>

+0

あなたは)} '閉鎖を持っていない;'これは奇妙ですが、私は – Grisza

+0

おかげで、Grisza、Sorry..closingを})作品のために。行方不明だった...しかし、上記の誤植だけ。反復がどこにあるのか、それがどのように役立つかはわかりません。 – kev

答えて

2

keyupあなたがキーを押したときに失敗し、それを解放する前に、別のキーを押します。ここでは

は、コードがあります。事象の順序は、keydown 1,keydown 2,keyup 1,keydown 2である。しかし、文字が​​(およびkeypress)の後に生成されると、その場合は最初のkeyupイベントの前にinputに2つの文字が既に存在します。これは、任意の変化に即座にトリガされ

$('.pinchar').on('input', function (e) { 
     // ... etc. 

代わりinputイベントを試してみてください。

しかし、他のキーを正しく処理するには、​​イベントもトラップする必要があります(矢印キーとバックスペースキー用)。

私はこのコードを示唆している:上記のコードは、あなたがそれが現在のものに取って代わる別の文字を入力するとなるように、常に、現在の文字を選択することを目指していること

function step(inp, dir, clr) { 
 
    if (clr) $(inp).val(''); 
 
    var $next = $(inp).parent()[['prev','next'][dir]]().find('.pinchar'); 
 
    if (!$next.length) $next = $(inp); 
 
    $next.focus(); 
 
    setTimeout(function() { 
 
     $next.select(); 
 
    }, 0); 
 
    return false; 
 
} 
 
$(document).ready(function() { 
 
    $('.pinchar').on('focus', function() { 
 
     $(this).select(); // always select the "whole" (1 char) text 
 
    }); 
 
    $('.pinchar').on('keydown', function (e) { 
 
     // arrows 
 
     if (e.which == 37 || e.which == 38) return step(this, 0); 
 
     if (e.which == 39 || e.which == 40) return step(this, 1); 
 
     // backspace 
 
     if (e.which == 8) return step(this, 0, 1); 
 
    }); 
 
    $('.pinchar').on('input', function (e) { 
 
     step(this, 1); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<table class="enterPINTable"> 
 
    <tr> 
 
    <td> 
 
     <input name="txtPIN1" id="txtPIN1" class="pinchar" size="1"> 
 
    </td> 
 
    <td> 
 
     <input name="txtPIN2" id="txtPIN2" class="pinchar" size="1"> 
 
    </td> 
 
    <td> 
 
     <input name="txtPIN3" id="txtPIN3" class="pinchar" size="1"> 
 
    </td> 
 
    <td> 
 
     <input name="txtPIN4" id="txtPIN4" class="pinchar" size="1"> 
 
    </td> 
 
    </tr> 
 
</table>

注意を。

またleftrighttab、+ tabshiftbackspace、およびdeleteキー期待できるとして働いています。

+0

優れています。うまく動作し、私は矢印abdのバックスペースの処理が好きです。ありがとう。 – kev

2

この場合、キープレスが適しています。

問題は、キーアップがkeypownとkeypressの後に遅くトリガーされることです。

キーが押されたとき、即座のkeydownイベントがトリガされます。

これは順序が行く方法です。その場合、値は画面に表示されません。キーを押すと、この時点で値が表示されます。
両方のイベントの後、キーから指を離すと、キーアップがトリガーされます。

2つのキーをすばやく押すと、キー入力がすぐに連続して呼び出されるため(値が画面に表示されるとき)、同じ入力に値が印刷され、次に両方にキーアップが呼び出され、次のキー入力中に値がすでに印刷されているため、空白にしておきます。

$(document).ready(function() { 
 

 
      $('.pinchar').keypress(function (e) { 
 
\t \t \t \t 
 
       $(this).parent().next().find('.pinchar').focus(); 
 
       
 
      }); 
 
    
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<table class="enterPINTable"> 
 
     <tr> 
 
     <td> 
 
      <input name="txtPIN1" id="txtPIN1" class="pinchar" size="1"> 
 
     </td> 
 
     <td> 
 
      <input name="txtPIN2" id="txtPIN2" class="pinchar" size="1"> 
 
     </td> 
 
     <td> 
 
      <input name="txtPIN3" id="txtPIN3" class="pinchar" size="1"> 
 
     </td> 
 
     <td> 
 
      <input name="txtPIN4" id="txtPIN4" class="pinchar" size="1"> 
 
     </td> 
 
     </tr> 
 
    </table>

+0

keypressは廃止されましたが、クロスブラウザサポートを考慮しないとすべてのブラウザで機能しないok – Grisza

+0

これも機能します。多分、Griszaはkeypressが非難されることについてのポイントを持っていますが、この解決策も機能します。 – kev

関連する問題