JavaScript: проверка ввода в событии keydown - PullRequest
6 голосов
/ 08 июня 2010

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

Проверка IЯ пишу так:

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. Условное выражение становится длиннее и длиннее, когда я ставлю больше условий для проверки.
  2. keyCodes может отличаться в зависимости от браузера.
  3. Я должен не только проверить, что не законно, но и проверить, что является исключительным.В приведенных выше примерах клавиши delete , backspace и arrow являются исключительными.

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

Поэтому мой вопрос:

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

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

Ответы [ 4 ]

14 голосов
/ 08 июня 2010

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

Есть также некоторые ошибки: в 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;
    }
};
1 голос
/ 08 июня 2010

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

Я не могу придумать лучших способов использования keyCode. Вы можете использовать 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;
}
0 голосов
/ 29 августа 2013

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

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

0 голосов
/ 17 ноября 2012

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

jsfiddle: демонстрация нажатия / нажатия клавиш с информационным дисплеем

Похоже, что в последних браузерах используется protectDefault (). Приведенный ниже код аналогичен тому, что я поместил в 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>
...