博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
写一个js表单验证框架
阅读量:4980 次
发布时间:2019-06-12

本文共 5402 字,大约阅读时间需要 18 分钟。

其实我自己也就能简单用用js而已,但是呢,相对很多初学者来说多懂了点Know How所以斗
胆孟浪一下,将一些所得记录下来,以供更多的初学者能够知道一个东西的实现过程,省去
在源码里摸索的过程。
在表单程序中,在页面上需要很多的Js代码来验证表单,每一个field是否必须填写,是否
只能是数字,是否需要ajax到远程验证,blablabla。
如果一个一个单独写势必非常的繁琐,所以我们的第一个目标就是构建一个类似DSL的东西,
用表述的语句而非控制语句来实现验证。
其次一个个单独写的话还有一个问题就是必须全部验证通过才能提交,但是单独验证会因为
这个特征而增加很多额外的控制代码,且经常会验证不全面。所以第二个目标就是能够全面
的整合整个验证的过程。
最后不能是一个无法扩展的一切写死的实现,必要的扩展性还是要的。
首先,我们需要一个能够描述对字段验证的类
 
代码
1 
function
 Field(params){
2 
    
this
.field_id
=
params.fid;     
//
要验证的字段的ID
3 
    
this
.validators
=
params.val;   
//
验证器对象数组
4 
    
this
.on_suc
=
params.suc;       
//
当验证成功的时候执行的事件
5 
    
this
.on_error
=
params.err;     
//
当验证失败的时候执行的事件
6 
    
this
.checked
=
false
;           
//
是否通过验证
7 
}
8 

 

关于验证器对象我们在后面来讨论,接下来我们扩展这个类,加入validate方法
 
代码
 1 
Field.prototype.validate
=
function
(){
 2 
    
//
循环每一个验证器
 3 
    
for
(item 
in
 
this
.validators){
 4 
        
//
给验证器附加验证成功和验证失败的回调事件
 5 
        
this
.set_callback(
this
.validators[item]);
 6 
        
//
执行验证器上的Validate方法,验证是否符合规则
 7 
        
if
(
!
this
.validators[item].validate(
this
.data())){
 8 
            
break
//
一旦任意一个验证器失败就停止
 9 
        }
10 
    }
11 
}

 

再加入一个获取字段值的方法:
 
1 
//
获取字段值的方法
2 
Field.prototype.data
=
function
(){
3 
    
return
 document.getElementById(
this
.field_id).value;
4 
}

 

 
设置验证器回调函数的方法set_callback如下:
 
代码
 1 
Field.prototype.set_callback
=
function
(val){
 2 
    
var
 self
=
this
;              
//
换一个名字来存储this,不然函数的闭包中会覆盖这个名字
 3 
    val.on_suc
=
function
(){      
//
验证成功执行的方法
 4 
        self.checked
=
true
;      
//
将字段设置为验证成功        
 5 
        self.on_suc(val.tips);  
//
执行验证成功的事件
 6 
    }
 7 
    val.on_error
=
function
(){    
//
验证失败的时候执行的方法
 8 
        self.checked
=
false
;     
//
字段设置为验证失败
 9 
        self.on_error(val.tips);
//
执行验证失败的事件
10 
    }
11 
}

 

 
接下来我们就来看看验证器,验证器是真正执行验证过程的类,根据一般的验证过程,我们
可以将其分类成,长度验证(包括必填验证),正则表达式验证,自定义函数验证,Ajax远
程验证这几种,所以我们定义这几种验证器类,Ajax远程验证为了方便引用了jQuery,其他
部分也有用到:
 
代码
 1 
 2 
//
长度验证的验证器类
 3 
function
 Len_val(min_l,max_l,tip){
 4 
    
this
.min_v
=
min_l;
 5 
    
this
.max_v
=
max_l;
 6 
    
this
.tips
=
tip;
 7 
    
this
.on_suc
=
null
;
 8 
    
this
.on_error
=
null
;
 9 
}
10 
Len_val.prototype.validate
=
function
(fd){
11 
    
if
(fd.length
<
this
.min_v
||
fd.length
>
this
.max_v){
12 
        
this
.on_error();
13 
        
return
 
false
;
14 
    }
15 
    
this
.on_suc();
16 
    
return
 
true
;
17 
}
18 
//
正则表达式验证器
19 
function
 Exp_val(expresion,tip){
20 
    
this
.exps
=
expresion;
21 
    
this
.tips
=
tip;
22 
    
this
.on_suc
=
null
;
23 
    
this
.on_error
=
null
;
24 
}
25 
Exp_val.prototype.validate
=
function
(fd){
26 
    
if
(
!
fd){
27 
        
this
.on_suc();
28 
        
return
 
true
;
29 
    }
30 
    
if
(
this
.exps.test(fd)){
31 
        
this
.on_suc();
32 
        
return
 
true
;
33 
    }
else
{
34 
        
this
.on_error();
35 
        
return
 
false
;
36 
    }
37 
}
38 
//
远程验证器
39 
function
 Remote_val(url,tip){
40 
    
this
.p_url
=
url;
41 
    
this
.tips
=
tip;
42 
    
this
.on_suc
=
null
;
43 
    
this
.on_error
=
null
;
44 
}
45 
Remote_val.prototype.validate
=
function
(fd){
46 
    
var
 self
=
this
;
47 
    $.post(
this
.p_url,{f:fd},
48 
        
function
(data){
49 
            
if
(data.rs){
50 
                self.on_suc();
51 
                
return
;
52 
            }
else
{
53 
                self.on_error();
54 
            }
55 
        },
"
json
"
56 
    );
57 
    
return
 
false
;
58 
}
59 
//
自定义函数验证器
60 
function
 Man_val(tip,func){
61 
    
this
.tips
=
tip;
62 
    
this
.val_func
=
func;
63 
    
this
.on_suc
=
null
;
64 
    
this
.on_error
=
null
;
65 
}
66 
Man_val.prototype.validate
=
function
(fd){
67 
    
if
(
this
.val_func(fd)){
68 
        
this
.on_suc();
69 
    }
else
{
70 
        
this
.on_error();
71 
    }
72 
}

 

最后我们用一个userform的类来做一个入口,在构造的时候传入Field对象的列表,并且将
每一个控件的onblur事件绑定到validate的包装器上
 
代码
 1 
function
 UserForm(items){
 2 
    
this
.f_item
=
items;                             
//
把字段验证对象数组复制给属性
 3 
    
for
(idx
=
0
;idx
<
this
.f_item.length;idx
++
){       
//
循环数组
 4 
        
var
 fc
=
this
.get_check(
this
.f_item[idx]);   
//
获取封装后的回调事件
 5 
        $(
"
#
"
+
this
.f_item[idx].field_id).blur(fc); 
//
绑定到控件上
 6 
    }
 7 
}
 8 
//
绑定验证事件的处理器,为了避开循环对闭包的影响
 9 
UserForm.prototype.get_check
=
function
(v){
10 
    
return
 
function
(){   
//
返回包装了调用validate方法的事件
11 
        v.validate();
12 
    }
13 
}
14 

 

接下来需要定义一个方法来绑定提交按钮的onclick事件:
代码
 1 
//
绑定提交事件到元件
 2 
UserForm.prototype.set_submit
=
function
(bid,bind){
 3 
    
var
 self
=
this
;
 4 
    $(
"
#
"
+
bid).click(
 5 
        
function
(){
 6 
            
if
(self.validate()){
 7 
                bind();
 8 
            }
 9 
        }
10 
    );
11 
}

 

这里提到了一个UserForm的validate方法,如下:
代码
 1 
//
验证所有的字段
 2 
UserForm.prototype.validate
=
function
(){
 3 
    
for
(idx 
in
 
this
.f_item){             
//
循环每一个验证器
 4 
        
this
.f_item[idx].validate();     
//
再检测一遍
 5 
        
if
(
!
this
.f_item[idx].checked){   
 6 
            
return
 
false
;                
//
如果错误就返回失败,阻止提交
 7 
        }
 8 
    }
 9 
    
return
 
true
;                         
//
一个都没错就返回成功执行提交
10 
}

 

 
最后用一个例子来看看怎么用:
 
代码
 1 
<
html
>
 2 
<
head
>
 3 
<
meta 
http-equiv
="Content-Type"
 content
="text/html; charset=utf-8"
/>
 4 
<
title
>
test
</
title
>
 5 
<
script 
type
="text/javascript"
 src
="jquery-1.4.2.min.js"
></
script
>
 6 
<
script 
type
="text/javascript"
 src
="kernel.js"
></
script
>
 7 
<
script 
type
="text/javascript"
>
 8 
var
 form;
 9 
$(
10 
function
(){
11 
    
var
 uf
=
new
 UserForm([
new
 Field({
12 
            fid:
"
f1
"
,
13 
            val:[
new
 Len_val(
1
,
5
,
"
长度错误
"
),
new
 Exp_val(v_int,
"
不是数字
"
)],
14 
            suc:
function
(text){
15 
                $(
'
t1
'
).val(
''
);
16 
                $(
'
t1
'
).attr(
'
class
'
,
'
suc
'
);
17 
            },
18 
            err:
function
(text){
19 
                (
'
t1
'
).val(text);
20 
                $(
'
t1
'
).attr(
'
class
'
,
'
error
'
);
21 
            }
22 
        })
23 
    ]);
24 
    uf.set_submit(
25 
        
"
bt
"
,
26 
        
function
(form){
27 
            alert(
"
表单已经提交了
"
);
28 
        }
29 
    );
30 
}
31 
);
32 
</
script
>
33 
<
style
>
34 
.suc 
{
 background-color
:
#00ff00
;
}
35 
.error 
{
 background-color
:
#ff0000
;
}
36 
</
style
>
37 
</
head
>
38 
<
body
>
39 
<
input 
type
="text"
 id
="f1"
 name
="f1"
/><
span 
id
="t1"
></
span
><
br
/>
40 
<
input 
type
="button"
 id
="bt"
 value
="提交"
/>
41 
</
body
>
42 
</
html
>

 

 
要注意的地方就是在
循环中使用闭包会茶几,必须用一个方法来代理一下,呵呵
 
希望对初学js但是还不知道该做点什么怎么做的朋友能有所帮助
 

 

 

严重声明:本文版权属原作者所有    本文重在收藏和学习

 

原文地址:http://www.cnblogs.com/Alexander-Lee/archive/2010/09/13/1825353.html

转载于:https://www.cnblogs.com/yonge/archive/2011/11/25/2263521.html

你可能感兴趣的文章
PHP实现的快速排序
查看>>
AE属性表操作
查看>>
2进制_8进制_16进制之间快速转换的技巧.txt
查看>>
Python学习(五)函数 —— 内置函数 lambda filter map reduce
查看>>
[转] PDB文件概说
查看>>
再坚持一年多就写代码到40岁了,一直坚持.NET也没什么大错,傻B青年快乐多重新回归博客园...
查看>>
hbase安装配置
查看>>
How to publish a WordPress blog to a static GitLab Pages site
查看>>
面试人生
查看>>
JAVA多线程之当一个线程在执行死循环时会影响另外一个线程吗?
查看>>
红黑树总结(1)
查看>>
学习笔记
查看>>
Mindjet.MindManager“参数错误”解决办法,适用于9.0、10.0和14.0
查看>>
第7章学习小结
查看>>
Continue Posting, Keep Fighting
查看>>
C# .net MD5加密函数
查看>>
Spring Cloud 入门 之 Config 篇(六)
查看>>
I/O多路复用
查看>>
Spring Cloud Eureka 集群搭建 - 以及发现一个 “直觉BUG”
查看>>
Quartz使用总结
查看>>