![](https://img-blog.csdnimg.cn/img_convert/b08c999cce8d18ae921b60e6ccdd660e.jpeg)
一、三种情况下触发验证事件
- 输入框失去焦点 -> $('input[!type=button]').blur(function() {})
- 输入框输入中 -> $('input[!type=button]').bind('input propertychange', function() {})
- 点击提交表单时 -> $('input[type=button]').onclick(function(){ $.ajax({ }) })
表单HTML部分如下
<form id="signup_valid" name="signup_form">
<a class="signup_btn_close" href="javascript:" onclick="signupLayer('signup_layer', false)"></a>
<h1 class="signup_top">
<em class="l"></em>报名资料<em class="r"></em>
</h1>
<div class="signup_center">
<div class="el">
<input id="signup_city" class="in" name="signup_city" type="text" placeholder="城市" />
</div>
<div class="el">
<input id="signup_com" class="in" name="signup_com" type="text" placeholder="学校" />
</div>
<div class="el">
<input id="signup_name" class="in" name="signup_name" type="text" placeholder="联系人姓名" />
</div>
<div class="el">
<input id="signup_tel" class="in" name="signup_tel" type="text" placeholder="联系电话" />
</div>
</div>
<div class="signup_bottom">
<input id="signup_submit" class="signup_btn" type="button" value="立即报名" />
</div>
</form>
二、表单验证及ajax异步提交数据JS
// 弹框弹出关闭事件
// 触发元素中加入onclick="signupLayer('弹框层ID', Boolean)"
// Boolean=>true 或 false, 弹出为true, 关闭为false
function signupLayer(el, dis) {
var isShow = dis ? "block" : "none";
// 获取弹框元素
$("#" + el).css('display', isShow);
// 遮罩层
$("#layer_back_drop").css('display', isShow);
}
// 定义待验证项
var validate = {
signup_city: {
required: true, // 必填项
maxLength: 4 // 长度项
},
signup_com: {
required: true,
maxLength: 20
},
signup_name: {
required: true,
maxLength: 4
},
signup_tel: {
required: true,
mobile: true
}
/**
待验证元素ID: {
验证项: value
}
*/
};
// 定义错误信息提示
var msg = {
signup_city: {
required: '请输入城市',
maxLength: '输入超出4个汉字'
},
signup_com: {
required: '请输入学校名称',
maxLength: '输入超出20个汉字'
},
signup_name: {
required: '请输入姓名',
maxLength: '输入超出4个汉字'
},
signup_tel: {
required: '请输入手机号',
mobile: '请输入正确的手机号'
}
/**
待验证元素ID: {
验证项: 错误提示信息
}
*/
};
// 定义验证方法
var methods = {
// 必填项
required: function(value) {
// 去除首尾空格
// !String.prototype.trim 用于兼容IE版本
var v = !String.prototype.trim ? value.replace(/^\s+|\s+$/gm, '') : value.trim();
// 为空返回false, 有值返回true
return Boolean(v);
},
// 最大长度
// value -> 输入的值;length => validate中定义的maxlength值
maxLength: function(value, length) {
// 去除首尾空格
var v = !String.prototype.trim ? value.replace(/^\s+|\s+$/gm, '') : value.trim();
// 匹配非中文字符,用于重新计算长度
var chNon = v.match(/[^\u4E00-\u9FA5\uf900-\ufa2d]+/g) ? v.match(/[^\u4E00-\u9FA5\uf900-\ufa2d]+/g).join('') : '';
// 匹配中文字符
var ch = v.match(/[\u4E00-\u9FA5\uf900-\ufa2d]+/g) ? v.match(/[\u4E00-\u9FA5\uf900-\ufa2d]+/g).join('') : '';
// 4个非中文字符按一个中文字符计算,相加换算最终长度
var vLen = chNon.length + (ch.length * 4);
// 小于限定长度则返回true,大于限定长度则返回false
return vLen <= length;
},
// 手机号码
mobile: function(value) {
// 去除空值
var v = value.replace(/\s/g, "");
// 手机号码的格式匹配
var res = /^(0|86|17951)?(13[0-9]|15[012356789]|16[6]|19[89]]|17[01345678]|18[0-9]|14[579])[0-9]{8}$/;
// 匹配一致则返回true,否则false
return res.test(v);
}
};
// 定义可调用的函数
function validEvent(e) {
// 每次触发该事件前,若当前元素已有错误提示,则移除(避免重复返回错误提示信息)
$(e).siblings('.error').remove();
var error = $('<label class="error"></label>'); // 创建错误提示信息容器
var errorText; // 错误提示信息文本
var key = e.id; // 当前触发元素的id
var len = validate[key].maxLength * 4; // 当前触发元素的限定长度,非中文字符占4个中文字符长度
var val = e.value; // 当前触发元素的输入值
// 元素定义的验证项
var rq = validate[key].required,
mx = Boolean(validate[key].maxLength),
ph = Boolean(validate[key].mobile);
// 元素定义的验证处理事件
var v_rq = methods.required(val),
v_mx = methods.maxLength(val, len),
v_ph = methods.mobile(val);
/** 此处的判断逻辑待后续优化,感觉不是很美好 **/
if (rq && !v_rq) {
// 必填元素为空时执行
errorText = msg[key].required;
error.text(errorText);
$(e).removeClass('valid')
$(e).after(error);
} else if (v_rq && mx && !v_mx) {
// 元素不为空但长度超出限定执行
errorText = msg[key].maxLength;
error.text(errorText);
$(e).removeClass('valid')
$(e).after(error);
} else if (v_rq && ph && !v_ph) {
// 元素不为空,但不符合输入规范执行此
errorText = msg[key].mobile;
error.text(errorText);
$(e).removeClass('valid')
$(e).after(error);
}
// 为通过验证的元素添加validClass
// 为后续提交表单检测提供服务
// 感觉不是很美好,后续进行优化
if ((v_rq && v_mx) || (v_rq && v_ph)) {
var valid = $(e).hasClass('valid');
if (!valid) $(e).addClass('valid');
}
}
$(function() {
// 获取表单中待验证的元素,排除input[type!=button]
// 此次做的是非常简单的一个验证提交,只对input[type=text]进行验证
var $valid = $('#signup_valid').find('input[type!=button]');
// each循环执行
$valid.each(function() {
$(this).blur(function(){
// 元素失去焦点后执行事件,
validEvent(this);
});
$(this).bind('input propertychange', function(){
// 元素值发生变化后执行事件,
validEvent(this);
});
})
// 点击提交
$('#signup_submit').click(function() {
var validAll = []; // 定义一个空数组,用于存储通过验证的元素项
var data = {}; // 定义一个空对象,用于传输的数据值
$valid.each(function() {
// 循环执行
validEvent(this);
// 通过判断待验证的元素class是否具备valid
// 具备valid则证明验证项通过输入正确,插入数组validAll中
if ($(this).hasClass('valid')) {
validAll.push(this.id);
}
var key = this.name; // 元素name
var value = this.value; // 元素输入的值
data[key] = value; // 将每一个each循环到的元素插入对象data中
})
// 通过判断validAll数组长度与待验证项是否匹配,来确定表单是否通过验证,执行提交
// $valid.length好像不太对,应该获取validate
if (validAll.length == $valid.length) {
// 通过则执行如下,ajax异步提交
$.ajax({
type: "POST",
url: "./post.php",
data: data,
dataType: "html",
success:function showResponse(responseJson, statusText) {
$('#signup_sucess .signup_suc p').remove(); // 避免后续多次提交,重复插入提示信息,执行前先移除,无则不执行此段
$('#signup_sucess .signup_suc').append('<p>报名成功</p>'); // 插入提示信息
$('#signup_sucess').show().delay(3000).fadeOut(); // 显示3秒后自动隐藏
$('#layer_back_drop').delay(3000).fadeOut(); // 遮罩层同上
}
})
}
})
});
三、提交成功的提示弹框及遮罩层HTML
<div id="signup_sucess" class="popup_wrap" style="display: none;">
<div class="signup_suc">
<a class="signup_sucess_close" href="javascript:" onclick="signupLayer('signup_sucess', false)"></a>
</div>
</div>
<div id="layer_back_drop" class="layer_back_drop" style="display: none;"></div>
四、实现效果
五、Node.js 服务器的搭建见前面的学习