JavaScript: проверка ввода в событии keydown


Я пытаюсь выполнить проверку информации против ввода текста Пользователем в процессе события keydown. Причина, по которой я пытаюсь проверить в событии keydown, заключается в том, что я не хочу отображать символы, которые считаются незаконными в поле input в начале.

Проверка, которую я пишу, выглядит так:

function validateUserInput(){
   var code = this.event.keyCode;
    if ((code<48||code>57) // numerical
      &&code!==46 //delete
      &&code!==8  //back space
      &&code!==37 // <- arrow 
      &&code!==39) // -> arrow
   {
     this.event.preventDefault();        
    }
}

Я могу продолжать в том же духе, однако я вижу недостатки в этой реализации. Таковы, например: пример:

    Условное утверждение становится все длиннее и длиннее, когда я ставлю больше условий для рассмотрения.
  1. keyCodes может отличаться по браузерам.
  2. Я должен не только проверить то, что не является законным, но и проверить то, что является исключительным. В приведенных выше примерах удалить, клавиши backspace иarrow являются исключительными.

Но особенность, которую я не хочу потерять, состоит в том, что мне не нужно отображать входные данные в textarea, если это не проходит проверку. (В случае, если пользователь попытается поместить незаконные символы в textarea, ничего не должно появиться вообще), поэтому я не делаю проверку на событие keyup.

Итак, мой вопрос:

  1. есть ли лучшие способы проверки входных данных в событии keydown, чем проверка keyCode с помощью keyCode?
  2. есть ли другие способы захвата входных данных пользователя, кроме keydown события, прежде чем браузер отобразит его? И способ поставить на него проверку?

Спасибо за помощь заранее.

4 6

4 ответа:

Если вы проверяете печатаемый ключ, что именно то, что вы, кажется, делаете, вы должны использовать событие keypress вместо этого, так как это единственное место, где вы сможете получить достоверную информацию о символе, который представляет нажатие клавиши. Вы не можете надежно обнаружить числовые нажатия клавиш в событии keydown. Кроме того, это плохая идея, чтобы подавить клавиши со стрелками и удалить/backspace клавиши. Что вы получаете от этого?

Есть также некоторые ошибки: в Firefox вам нужно будет получить Event объект из параметра, переданного в функцию обработчика событий, и если вы используете функцию обработчика событий DOM0, а не addEventListener() или attachEvent(), вы должны использовать return false; для подавления поведения по умолчанию. Вот мой рекомендуемый код:

var input = document.getElementById("your_input_id");

input.onkeypress = function(evt) {
    evt = evt || window.event;
    var charCode = evt.which || evt.keyCode;
    var charStr = String.fromCharCode(charCode);
    if (/\d/.test(charStr)) {
        return false;
    }
};

Я не думаю, что вам нужна часть preventDefault. Если вы хотите поймать ключи (по event.keyCode, или комбинации, используя, например event.ctrlKey + event.keyCode), вы проверяете, разрешено ли keyCode. Если это так, просто верните true, в противном случае верните false. Если вы вернете false, то ключ ввода не будет записан в поле ввода, иначе он будет записан.

Я не могу придумать лучшего способа, чем использовать код ключа. Вы можете использовать String.fromCharCode([keyCode]), Если хотите проверить конкретные значения символов, но он продолжает сводиться к некоторым цикл для проверки кодов ключей, которые вы хотите проверить. Может быть, switch ... case может предложить немного больше читабельности.

Вот фрагмент кода из обработчика событий keydown, который я использую (просто для демонстрации, на самом деле он ничего не делает):

function handleKey(e, thisFld) {
        thisFld = (thisFld || this);
              e = e || event;
    if (!e) {
      return true;
    }

    var isCtrl = e.ctrlKey,
        isShift = e.shiftKey,
        isAlt = e.altKey,
        kc = e.keyCode || e.which,
        codes = [27, 38, 40],
        keys = {
                 escape: 27,
                 up: 38,
                 down: 40,
                 ins: 45,
                 del: 46,
                 one: 49
                };

    if (isCtrl && kc === keys.del) { ... }
    if (isAlt && kc === keys.ins) { ... }
        //etc
    return true;
}

Вот скрипка, с которой вы можете играть и которая может дать вам больше понимания.

Jsfiddle: keydown / keypress demo w / info display

Похоже, что последние браузеры используют функцию preventDefault (). Приведенный ниже код аналогичен тому, что я поставил на jsfiddle, но является автономным и может быть вставлен в html-файл, к которому вы можете получить доступ локально для тестирования (обратите внимание, что он удобен для мобильных устройств для тестирования устройств.

<html>
<head>
<meta name="viewport" content="initial-scale=1, minimum-scale=1, maximum-scale=1, width=device-width, user-scalable=no"/>
<style>
.b {color:blue;}
.r {color:red;}
input {font-size:18px;}
</style>
<script>
function byId(el) {return document.getElementById(el)}
function sfcc (n) {return String.fromCharCode(n);}
function foo(event) {
    var he='&#x'+event.keyIdentifier.split('+')[1]+';';
    var html=''
    var cn=event.target.className;
    html+='kc: [<span class="b">'+sfcc(event.keyCode)+'</span>] ';
    html+='wh: [<span class="b">'+sfcc(event.which)+'</span>] ';
    html+='he: [<span class="b">'+he+'</span>]<br>';
    for (i in event) 
        if (["string","boolean","number"].indexOf(typeof event[i]) >-1 && i.toUpperCase()!=i)
            html+='<span>'+i + '</span>: [<span class="r">'+event[i]+'</span>]<br>';
    byId('kc').innerHTML=html;
    switch (cn) {
        case "pd": event.preventDefault(); return;
        case "rf": return false;
    }
}
</script>
</head>
<body>
kp/pd: <input class="pd" type="text" onkeypress="foo(event)"/><br>
kp/rf: <input class="rf" type="text" onkeypress="foo(event)"/><br>
kd/pd: <input class="pd" type="text" onkeydown="foo(event)"/><br>
kd/rf: <input class="rf" type="text" onkeydown="foo(event)"/><br>
<div id="kc"></div>
</body>
</html>

Итак, я обнаружил, что нажатие клавиши отлично подходит для печати символов, а keydown-для всего остального. Вы можете проверить event.charCode на keypress для печатаемых символов (это должно быть 0 для непечатаемых). Вы можете использовать event.keyCode на keydown для стрелок и тому подобного.

Вот как я только что получил автозаполнение для работы в Chrome и Firefox.