7

我正在尝试在事件过程中对用户文本输入进行信息验证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. 我不仅要检查什么是不合法的,还要检查什么是例外的。在上面的示例中deletebackspace、 和arrow键是例外的。

但是我不想失去的功能是不必在中显示输入,textarea除非它通过验证。(如果用户尝试在 中输入非法字符,则textarea根本不会出现任何内容)这就是为什么我不对keyup事件进行验证的原因。

所以我的问题是:

  1. 有没有比通过keydown检查更好的方法来验证事件中的输入?keyCodekeyCode
  2. 除了事件之外,还有其他方法可以keydown在浏览器显示之前捕获用户输入吗?以及一种对其进行验证的方法?
4

4 回答 4

14

如果您正在检查一个可打印的键,这正是您似乎正在做的事情,您应该使用该keypress事件,因为这是您能够获得有关按键所代表的字符的可靠信息的唯一地方。您无法在keydown事件中可靠地检测到数字按键。此外,禁止箭头键和删除/退格键也是一个坏主意。你这样做有什么收获?

还有一些错误:在 Firefox 中,您需要Event从传递给事件处理函数的参数中获取对象,如果您使用的是 DOM0 事件处理函数而不是addEventListener()or 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;
    }
};
于 2010-06-08T15:43:39.710 回答
1

我认为您不需要 preventDefault 部分。如果您想捕获键(通过event.keyCode,或使用例如event.ctrlKey+的组合event.keyCode),请检查是否keyCode允许。如果是,则简单地返回true,否则返回false。如果 return false,则不会将键输入写入输入字段,否则会。

我想不出更好的方法来使用 keyCode。如果你想检查特定的字符值,你可以使用String.fromCharCode([keyCode])它,但它会一直沸腾到一些循环来检查你想要验证的 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;
}
于 2010-06-08T15:26:03.397 回答
0

这是一个你可以玩的小提琴,可以提供更多的洞察力。

jsfiddle:带信息显示的 keydown/keypress 演示

最新的浏览器似乎使用 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>
于 2012-11-17T15:10:38.083 回答
0

所以,我发现 keypress 非常适合可打印的字符,而 keydown 则适用于所有其他字符。您可以检查可打印字符的event.charCodeon keypress(对于不可打印字符,它应该为 0)。您可以将event.keyCodeonkeydown用于箭头等。

这就是我刚刚在 Chrome 和 Firefox 中获得自动完成功能的方式。

于 2013-08-29T13:54:12.607 回答