Write By Monkeyfly
以下内容均为原创,如需转载请注明出处。
前提
今天在看别人自定义的一个必填项的表单验证的方法时,发现一个问题:
HTML代码:
//data-empty 自定义的属性 存在的话 说明是必填项 不存在 则说明不是必填的
<input type="text" placeholder="存在data-empty属性" data-empty="请输入用户名" >
<input type="text" placeholder="没有data-empty属性" >
<input type="text" placeholder="请输入手机或电话" data-empty="请输入手机或电话" data-pattern="^((0\d{2,3}-?\d{7,8})|(1[35784]\d{9}))$" >
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...
}