前提
今天在看别人自定义的一个必填项的表单验证的方法时,发现一个问题:
HTML代码:
//data-empty 自定义的属性 存在的话 说明是必填项 不存在 则说明不是必填的 <input type="text" placeholder="存在data-empty属性" data-empty="请输入用户名" > <input type="text" placeholder="没有data-empty属性" > <input type="text" placeholder="请输入手机或电话" data-empty="请输入手机或电话" data-pa
jQuery代码:
$(function(){ $("input").on('blur', function(event) { //错误信息的提示内容,已经提前在data-empty属性中定义好了 var empty = $(this).attr("data-empty"); //如果文本框的值为空,则进行弹窗提示 if($(this).val() ==""){ if(empty){ //弹窗提示 data-empty 中已定义好的错误提示信息(代码省略了) setTimeout(function(){ //1.5秒后移除该弹框提示(代码省略了) },1500) }else{ //如果文本框的值为空,而且没有data-empty属性,说明它不是必填项,则不用写else语句 alert("该文本框没有data-empty属性");//写else语句仅仅为了测试 } } //下面的正则验证,仅仅用于联系方式文本框(因为只适用于存在data-pattern属性且值不为空的情况) var pattern = new RegExp( $(this).attr('data-pattern') ); var result = pattern.test( $(this).val() ); if( $(this).val() && !result){ //弹窗提示“格式错误”,且1.5s后自动消失 setTimeout(function(){ //1.5秒后移除该弹框提示(代码省略了) },1500) } }); }
说明:
其实刚开始看时,愣是没看明白正则验证的前3行代码,不知道 result的值何时为true ,何时为false。 在查看了正则表达式相关知识和进行了相关的代码测试之后,才算是真正明白了。
分析:
首先,我们要知道RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。 其次,我们要知道创建 RegExp 对象的语法:new RegExp(pattern, attributes); 参数说明:
pattern:本意为模式,它是一个字符串,表示一种正则表达式的匹配模式,也可以是自定义的正则表达式。 attributes:【可选参数】本意为属性,是一个可选的字符串,包含3种属性:"g"、"i" 和 "m"。分别是:全局匹配、忽略大小写匹配和多行匹配。 注:如果 第一个参数pattern 是正则表达式,而不是字符串,则必须省略该参数。 返回值:一个新的 RegExp 对象,具有指定的模式和标志("g"、"i" 或 "m")。 正则表达式对象的方法:
test()方法用于检测一个字符串是否匹配某个模式。(模式就是创建正则表达式对象时传入的字符串参数) 语法:正则表达式对象.test(string) 返回值:如果字符串 string 中含有与 正则表达式对象 匹配的文本,则返回 true,否则返回false。
//1.首先看前两行代码,拆开来看 var pattern = new RegExp( $(this).attr('data-pattern') ); var result = pattern.test( $(this).val() ); //它可以看成是这两部分的结合,我们一一来判断它们值可能出现的情况。 var pattern = new RegExp( );//创建一个正则表达式对象 //括号内需要传递一个参数,指的是要匹配字符串的模式,即自定义的字符串过滤或称验证规则。 var result = pattern.test( $(this).val() ); //一般是结合正则表达式对象的test方法来使用。 $(this).attr('data-pattern')//获取该对象的自定义属性值
测试过程1:
var p = new RegExp(); console.log(p); /(?:)/ p.test(""); //true p.test("123"); //true p.test("aae"); //true
var p = new RegExp(""); console.log(p); /(?:)/ p.test(""); //true p.test("123"); //true p.test("asd"); //true
var p = new RegExp(undefined); console.log(p); /(?:)/ p.test(""); //true p.test("123"); //true p.test("1234aae"); //true
var p = new RegExp("undefined"); p.test("123"); //false p.test("asd"); //false
var p = new RegExp(null); p.test("123"); //false p.test("asd"); //false
测试结果1:
对于正则表达式对象p来说,如果创建对象时传入的字符串参数为空(""),传入一个undefined,或者没传任何参数,此时调用它的test()方法能匹配到任何字符串,因此test()方法的返回值都为true。(这相当于匹配的模式为""、undefined值、或无模式)
总结:pattern对象对空字符串("")、undefined值、空值的处理,都会导致test()方法返回true。
测试过程2:
//如果属性不存在,则返回undefined类型 <input type="text" > var empty = $(this).attr("data-empty"); //empty = undefined console.log(typeof empty); //undefined
//如果属性存在(不管是否为空)都返回string类型 <input type="text" data-empty="" > var empty = $(this).attr("data-empty"); //empty = "" console.log(typeof empty); //string
测试结果2:如果自定义属性存在,则返回string类型,如果自定义属性不存在,则返回undefined类型。
现在,这个问题就迎刃而解了
//可以这么说:此处只适用于存在data-pattern属性且值不为空的情况 var pattern = new RegExp( $(this).attr('data-pattern') ); var result = pattern.test( $(this).val() ); //如果不存在data-pattern属性,result只会返回true。 //要进行正则验证,输入框内肯定有值,所以 $(this).val() == true //!result 恒为 false //true && false == false //所以,只要不存在该属性,if语句是不会执行的 if( $(this).val() && !result){ //code... }