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();
}
}
Я могу продолжать в том же духе, однако я вижу недостатки в этой реализации. Таковы, например: пример:
-
Условное утверждение становится все длиннее и длиннее, когда я ставлю больше условий для рассмотрения.
-
keyCodes
может отличаться по браузерам.
Я должен не только проверить то, что не является законным, но и проверить то, что является исключительным. В приведенных выше примерах удалить, клавиши backspace иarrow являются исключительными.
Но особенность, которую я не хочу потерять, состоит в том, что мне не нужно отображать входные данные в textarea
, если это не проходит проверку. (В случае, если пользователь попытается поместить незаконные символы в textarea
, ничего не должно появиться вообще), поэтому я не делаю проверку на событие keyup
.
Итак, мой вопрос:
- есть ли лучшие способы проверки входных данных в событии
keydown
, чем проверкаkeyCode
с помощьюkeyCode
? - есть ли другие способы захвата входных данных пользователя, кроме
keydown
события, прежде чем браузер отобразит его? И способ поставить на него проверку?
Спасибо за помощь заранее.
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.