JavaScript:keydown事件中的输入验证

时间:2010-06-08 13:43:51

标签: javascript javascript-events validation 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. 当我提出更多条件进行审查时,条件陈述变得越来越长。
  2. keyCodes可能因浏览器而异。
  3. 我不仅要检查什么是不合法的,还要检查什么是例外情况。在上面的示例中, delete backspace arrow 键是例外。
  4. 但我不想丢失的功能是除非通过验证,否则不要在textarea中显示输入。 (如果用户试图在textarea中放入非法字符,则根本不会出现任何内容。这就是为什么我没有在keyup事件上进行验证。

    所以我的问题是:

    1. 是否有更好的方法来验证keydown事件中的输入,而不是通过keyCode检查keyCode
    2. 在浏览器显示之前,还有其他方法可以捕获keydown事件以外的用户输入吗?还有一种验证方法吗?
    3. 感谢您的帮助。

4 个答案:

答案 0 :(得分:14)

如果您正在检查可打印的密钥,这正是您正在做的事情,那么您应该使用keypress事件,因为这是您唯一可以获得可靠信息的地方关于按键所代表的角色。您无法在keydown事件中可靠地检测数字按键。此外,禁止箭头键和删除/退格键是一个坏主意。你从中获得了什么?

还有一些错误:在Firefox中,你需要从传递给事件处理函数的参数中获取Event对象,如果你使用的是DOM0事件处理函数而不是{{1或addEventListener(),您应该使用attachEvent()来抑制默认行为。这是我推荐的代码:

return false;

答案 1 :(得分:1)

我认为你不需要preventDefault部分。如果您想要抓住密钥(event.keyCode或使用例如event.ctrlKey + event.keyCode的组合),则检查是否允许keyCode。如果是,只需返回true,否则返回false。如果返回false,键输入将不会写入输入字段,否则将写入。

我想不出更好的方法来使用keyCode。如果要检查特定的字符值,可以使用String.fromCharCode([keyCode]),但它会一直循环到某个循环以检查要验证的keyCodes。可能是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;
}

答案 2 :(得分:0)

这里是您可以玩的小提琴,可能会提供更多见解。

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>

答案 3 :(得分:0)

所以,我发现按键对于可打印字符非常有用,而对于所有其他字符来说都是keydown。您可以检查event.charCode keypress上的可打印字符(对于不可打印的字符,它应为0)。 您可以在event.keyCode上使用keydown获取箭头等。

这就是我在Chrome和Firefox中使用自动完成功能的方法。