在输入时验证 html 文本输入

Posted

技术标签:

【中文标题】在输入时验证 html 文本输入【英文标题】:Validate html text input as it's typed 【发布时间】:2012-03-01 14:05:44 【问题描述】:

验证 html 文本输入的最佳方法是什么?我知道的所有方法都有一些缺点:

    使用$.keypress,您只能访问输入的旧值,而不能访问新值。此外,某些事件(如使用鼠标剪切/粘贴)将不会被检测到。

    仅当输入失去焦点时使用$.change

    This question 提出了一个解决方案,您可以使用轮询来监视属性更改。原则上,可以在回调中验证新值,如果无效则恢复为旧值。但是,除了需要轮询之外,我不确定它是否不受竞争条件的影响。

    This article 建议在存在时使用特定于浏览器的功能,如果没有可用则回退到轮询。看起来是迄今为止最好的方法。

    [Update] 正如答案中所指出的,$.keyup 允许在更新后访问该值。但是,它不仅对鼠标剪切/粘贴不起作用,而且如果您按住一个键也会失败,只有在输入很多后才能释放。或者,如果结合keydownkeyup 来保存/恢复旧值,如果用户输入太快,它就会中断。

以上解决方案都不是无错误或真正安全的跨浏览器。是否有更好的解决方案,无论是现成的还是正在制作的?好像是一个常见的问题,我最近尝试回答similarquestions,没有成功,我也有兴趣回答。

反对这种做法的一个很好的论据也很受欢迎,以防如果实施此验证会出现新问题;但是,这在其他语言中似乎很常见,所以我怀疑想要是一件坏事)

【问题讨论】:

【参考方案1】:

您可以使用input (FF) 和propertychange(所有其他)事件来捕获所有形式的输入,包括键盘和人民币剪切粘贴。

http://jsfiddle.net/dFBzW/

$('input').bind('input propertychange', function() 
    $('#output').html($(this).val());
);

【讨论】:

这是我目前找到的最好的答案,我在此基础上写了this example。在 FF、Chrome 和 Safari 上运行良好,在 IE6 上运行良好(有时会出现非致命的堆栈溢出,但谁在乎 IE6),但在 Opera(和 Konqueror,但我也不在乎)失败。所以我把这个问题留了一段时间...... @mgibsonbr - 对我来说似乎适用于 Opera 11.61。这个例子到底是做什么的? 它试图只让用户输入有效数字,但由于这是不可能的(当用户仍在输入时,值无效),它也接受有效前缀(如果整个文本无效,则显示红色边框)。因此,如果用户尝试添加或删除会使输入无效的字符,它将恢复为上次保存的值。否则,它将保存新值。 (但不一定是我在真实系统中要做的事情 - 请参阅 nnnnnn 的 answer)该示例在 Opera 10.63 上失败,但由于它适用于较新的版本,所以没问题! 第二次阅读(FF)FF代表什么?【参考方案2】:

也欢迎提出反对这种做法的好论据,以防如果实施此验证会出现新问题;然而,这在其他语言中似乎很常见,所以我怀疑这是一件坏事。

如果“验证”是指“完全防止输入无效字符”,我认为这是一种不好的做法。这会让用户感到困惑,他们可能没有密切关注,甚至在键入时甚至没有查看该字段(例如,如果他们正在输入他们正在从一张纸上读取的帐户或电话号码)。实际保存/使用的值可能与他们认为输入的值略有不同。

如果“验证”是指“测试当前值并通过例如在字段旁边显示错误或更改背景颜色来引起用户注意任何问题”,那么使用几种组合没有问题事件包括keyup、change、blur、paste、click:

$("field selector").on("keyup change blur paste cut click", function()  ... );

这将在用户键入时捕获大多数正常情况,对于剪贴板或拖放情况,您至少知道在最坏的情况下,当用户离开时,该字段仍将被验证。 (显然,在所有错误都更正之前,您不允许提交。)

如果您处理 keyup keydown 覆盖用户按住某个键的情况,因为大多数浏览器会为此发送重复的 keydown 事件。

【讨论】:

这些很好,从现在开始我会三思而后行。【参考方案3】:

在 jQuery 世界中,利用插件来完成这些验证任务是很常见的。插件相对容易使用,而且它们的受欢迎程度通常反映在比从头编写的代码更少的错误上。

输入验证通常分为几类,包括:

1) 正确的输入格式/输入掩码。例如,只有 A-Z,或者说,10 位数字。

2) 内容存在于域中。例如,机场代码或邮政编码。

(1)可以使用这些比较流行的插件:

Digital Bush's Masked Input Plugin for Jquery。它有许多自定义选项,包括空格,例如:

来自 Digital Bush 网站:

$("#phone").mask("(999) 999-9999");

autoNumeric from decorplanit.com 。它们对数字以及货币、四舍五入等都有很好的支持。

改编自 autoNumeric 网站:

$('#amountPaid').autoNumeric(aSep: '.', aDec: ','); // eg, 9.000,00

对于(2),您可以使用例如jQuery UI's autocomplete,结合服务器资源数据,采用JSON 等格式。这些可能需要自定义代码来锁定输入,但您仍然可以利用插件来实现基本功能,并专注于您正在创建的特定业务逻辑。

上面的一些文字改编自其他帖子here和here中的两个答案。

【讨论】:

+1 获取有用的参考资料。当涉及到剪切粘贴时,它们中的一些仍然表现得很奇怪,但对于最常见的情况,它们确实比替代方案更好。【参考方案4】:

你试过oninput吗?

HTML 示例:

<input name="username" id="user_name" oninput="readvalue();">

javascript

function readvalue() 
    var name = $('#user_name').val();

【讨论】:

【参考方案5】:

只是为了防止某些字符的另一种解决方案,没有 JQuery...

<input type="text" onkeypress="checkInput(event)" />

...

function checkInput(e)

    //only alpha-numeric characters
    var ok = /[A-Za-z0-9]/.test(String.fromCharCode(e.charCode));
    if (!ok)
        e.preventDefault();

我不知道这是否需要新版本的东西或仅适用于某些浏览器。请发表评论。

【讨论】:

等待不,它实际上没有:firefox 也阻止退格键、箭头键等。这似乎可以用|| e.charCode === 0 解决。【参考方案6】:

这里是代码

function validatephone(xxxxx) 

  var maintainplus = '';
  var numval = xxxxx.value
  if ( numval.charAt(0)=='+' )
  
    var maintainplus = '';
  
  curphonevar = numval.replace(/[\\A-Za-z!"£$%^&\-\)\(*+_=;:'@#~,.Š\/<>\" "\?|`¬\]\[]/g,'');
  xxxxx.value = maintainplus + curphonevar;
  var maintainplus = '';
  xxxxx.focus;
&lt;input type="text" align="MIDDLE" size="30" maxlength="20" onkeyup="validatephone(this);" name="contact"/&gt;

【讨论】:

OP 的问题是关于如何触发验证,而不是如何实现验证功能本身。他已经在他的问题中提到了 keyup。【参考方案7】:

这也可能有帮助

$(".cssclass").live("input propertychange", function () 
    //Validate goes here
);

【讨论】:

【参考方案8】:

function validatephone(xxxxx) 

  var maintainplus = '';
  var numval = xxxxx.value
  if ( numval.charAt(0)=='+' )
  
    var maintainplus = '';
  
  curphonevar = numval.replace(/[\\A-Za-z!"£$%^&\-\)\(*+_=;:'@#~,.Š\/<>\" "\?|`¬\]\[]/g,'');
  xxxxx.value = maintainplus + curphonevar;
  var maintainplus = '';
  xxxxx.focus;
&lt;input type="text" align="MIDDLE" size="30" maxlength="20" onkeyup="validatephone(this);" name="contact"/&gt;

【讨论】:

解释你的答案【参考方案9】:
let that=this;

$(this.element).find("input").keypress(function(e) 
               let character = String.fromCharCode(e.keyCode);

               let newValue =  this.value.substring(0,this.selectionStart) + character + this.value.substring(this.selectionEnd, String(this.value).length);


               if (!that.isFormatValid(newValue, that.getdecimalPoints())) 
                     e.preventDefault();
                     e.stopPropagation();
                     return false;
              

              return true;
        );


        $(this.element).find("input").bind(
              paste: function() 
                     let _this = this;

                     setTimeout( function() 
                           let decimals = that.getdecimalPoints();
                           if (!that.isFormatValid($(_this).val(), decimals))                         
                                         $(_this).val('');                        
                           
                     , 0);                                                                                                  
                  
           );

【讨论】:

使用代码的答案应该包括关于它如何回答问题的简短描述。

以上是关于在输入时验证 html 文本输入的主要内容,如果未能解决你的问题,请参考以下文章

当用户点击第 11 个号码时,如何验证输入文本(在 html 中)是不是是有效的电话号码?

PHP 表单验证

在输入时逐字母地验证UITextField文本

jQuery表单验证案例

WPF数据验证

用jquery怎么验证名字在输入完之后马上提示有没有重复的代码