2016-05-19 5 views
0

Я хочу, чтобы форма ввода PIN-кода, в которой каждый символ вводился в отдельный вход html.keyup change обработчик события фокус не работает для быстрого ввода

Я пытаюсь захватить события keyup в javascript, чтобы изменить фокус на следующий элемент ввода, избавив пользователя от необходимости самостоятельно его менять щелчком мыши или вкладкой.

Он работает, если пользователь не набирает очень быстро. Например, если пользователь набирает символы «1» и «2» очень быстро, я считаю, что первый вход теперь правильно имеет символ «1», а второй вход по-прежнему пуст, и фокус переместился на третий вход.

Почему?

Вот код:

$(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. Но поскольку символы создаются после keydownkeypress), у вас уже будет два символа в input перед первым keyup событием в этом случае.

Вместо попробовать input событие:

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

Он сразу же срабатывает при любом изменении.

Но для правильного лечения других ключей вам необходимо также захватить событие keydown (для клавиш со стрелками и назад).

Я хотел бы предложить этот код:

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>

Следует отметить, что приведенный выше код стремится всегда выбрать текущий символ, так что если вы наберете другой символ он заменяет текущий.

left Кроме того, right, tab, shift + tab, backspace и delete клавиши работают, как можно было бы ожидать.

+0

Отлично. Хорошо работает, и мне нравится обработка стрелок abd backspaces. Благодарю. – kev

2

Keypress лучше подходит для этого случая.

Проблема в том, что активация клавиатуры запускается поздно, то есть после нажатия клавиши и нажатия клавиши.

Это как заказ идет:

При нажатии клавиши, а затем мгновенно KeyDown событие. В этом случае значение не выводится на экран. После этого нажатие клавиши запускается, в это время значение печатается.
После обоих событий срабатывает клавиатура, когда вы поднимаете пальцы с клавиши.

Так что, когда вы быстро нажимаете две клавиши, их нажатие на клавиши вызывается быстро (это когда значение выводится на экран), поэтому значение печатается на одном и том же входе, затем нажимается клавиша для обоих, которая направляет фокус на следующий следующего ввода (оставляя их пустыми, потому что значение уже было напечатано во время нажатия клавиши).

$(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 устарел и не работает во всех браузерах, если мы рассмотрим поддержку кросс-браузера, если не считать так хорошо – Grisza

+0

Это также работает. Возможно, у Гриши есть точка в том, что keypress устарел, но, несмотря на это, это еще и решение. – kev