表单校验
本篇主要介绍使用 JavaScript 进行表单验证。
表单验证并不是 JavaScript 提供的某种特性,而是结合各种特性达到的一种目的,是需求的产物。
1. 验证目标
<form action="/login">
<label>
用户名:<input type="text">
</label>
<label>
密码:<input type="text">
</label>
<div>
<button type="submit">登入</button>
</div>
</form>
<label>
用户名:<input type="text">
</label>
<label>
密码:<input type="text">
</label>
<div>
<button type="submit">登入</button>
</div>·
其实不论是使用表单,还是不使用表单,表单的验证都是针对所有表单项的,即输入框、单选项、多选项等。
获取 DOM 节点的方式非常多,前面的章节也有介绍。
<style>
h3 {margin-top: ;color: #4caf50;}
.login {width: px;padding: px;Box-shadow: px px px rgba(, , , );position: fixed;top: ;left: ;transform: translate(-, -);}
.form-item {display: flex;margin-bottom: px;border-bottom: px solid #ccc;}
.form-item .title {width: px;color: #666;font-size: px;}
.form-item .content {flex: ;}
.form-item .content input {width: ;border: none;padding: px px;outline: none;font-size: px;}
.login-btn {width: ;border: none;background-color: #4caf50;color: white;margin-top: px;outline: none;height: px;}
.login-btn:active {background-color: #2da050;}
</style>
<form name="login-form" class="login">
<h3>登入</h3>
<label class="form-item">
<div class="title">用户名</div>
<div class="content">
<input id="account" class="account" name="account" type="text">
</div>
</label>
<label class="form-item">
<div class="title">密码</div>
<div class="content">
<input name="pwd" type="password">
</div>
</label>
<div>
<button class="login-btn" type="submit">登入</button>
</div>
</form>
<script>
var account1 = document.getElementById('account');
var account2 = document.getElementsByName('account');
var account3 = document.getElementsByClassName('account');
alert(account1 === account2[]);
alert(account1 === account3[]);
var account4 = document.forms['login-form']['account'];
alert(account1 === account4);
console.log(document.forms['login-form'].elements);
</script>
前三种获取节点的方式读者都已经熟悉了。
取到表单后,还可以直接使用表单项的 name 属性取到对应的表单项,使用 elements
可以取到这个表单下的所有表单项。
3. 校验表单项
<style>
h3 {margin-top: ;color: #4caf50;}
.login {width: px;padding: px;Box-shadow: px px px rgba(, , , );position: fixed;top: ;left: ;transform: translate(-, -);}
.form-item {display: flex;margin-bottom: px;border-bottom: px solid #ccc;}
.form-item .title {width: px;color: #666;font-size: px;}
.form-item .content {flex: ;}
.form-item .content input {width: ;border: none;padding: px px;outline: none;font-size: px;}
.login-btn {width: ;border: none;background-color: #4caf50;color: white;margin-top: px;outline: none;height: px;}
.login-btn:active {background-color: #2da050;}
</style>
<form name="login-form" class="login" action="https://imooc.com">
<h3>登入</h3>
<label class="form-item">
<div class="title">用户名</div>
<div class="content">
<input autocomplete="off" id="account" class="account" name="account" type="text">
</div>
</label>
<label class="form-item">
<div class="title">密码</div>
<div class="content">
<input autocomplete="off" name="pwd" type="password">
</div>
</label>
<div>
<button class="login-btn" type="submit">登入</button>
</div>
</form>
<script>
var loginForm = document.forms['login-form'];
var pwdEle = loginForm.pwd;
loginForm.onsubmit = function(e) {
var pwd = pwdEle.value;
if (pwd.length < || pwd.length > ) {
alert('密码长度 6-16');
return false; // 可以使用 return e.preventDefault() 代替
}
setTimeout(function() {
alert('登入成功,马上跳转!');
}, );
};
</script>
在事件处理器中,通过输入框的 value
属性获取到了输入的值,对值进行了长度判断,如果长度不正确则返回 false,表单则会终止提交。
如果正确,则会根据 form 标签的 target 属性进行提交。
需要注意的是,这里如果使用 addEventListener
来监听 submit
事件,必须使用 preventDefault
来阻止默认事件,即阻止表单提交,不能使用 return false;
。
var loginForm = document.forms['login-form'];
var pwdEle = loginForm.pwd;
loginForm.addEventListener('submit', function(e) {
var pwd = pwdEle.value;
if (pwd.length < || pwd.length > ) {
alert('密码长度 6-16');
e.preventDefault(); // 代替return false
return;
}
setTimeout(function() {
alert('登入成功,马上跳转!');
}, );
});
4. 不使用 form 提交表单
不使用 form 标签来提交表单,通常都是使用 AJAX 进行数据交互的情况。
这个时候就不需要拦截 form 的提交行为了。
<style>
h3 {margin-top: ;color: #4caf50;}
.login {width: px;padding: px;Box-shadow: px px px rgba(, , , );position: fixed;top: ;left: ;transform: translate(-, -);}
.form-item {display: flex;margin-bottom: px;border-bottom: px solid #ccc;}
.form-item .title {width: px;color: #666;font-size: px;}
.form-item .content {flex: ;}
.form-item .content input {width: ;border: none;padding: px px;outline: none;font-size: px;}
.login-btn {width: ;border: none;background-color: #4caf50;color: white;margin-top: px;outline: none;height: px;}
.login-btn:active {background-color: #2da050;}
</style>
<div class="login">
<h3>登入</h3>
<label class="form-item">
<div class="title">用户名</div>
<div class="content">
<input autocomplete="off" id="account" class="account" name="account" type="text">
</div>
</label>
<label class="form-item">
<div class="title">密码</div>
<div class="content">
<input autocomplete="off" name="pwd" type="password">
</div>
</label>
<div>
<button class="login-btn" type="button">登入</button>
</div>
</div>
<script>
var loginBtn = document.querySelector('.login-btn');
var pwdEle = document.querySelector('[name="pwd"]');
function login(cb) {
// 假装登入花了 1 秒
setTimeout(function() {
alert('登入成功');
cb && cb();
}, );
}
loginBtn.addEventListener('click', function() {
var pwd = pwdEle.value;
if (pwd.length < || pwd.length > ) {
alert('密码长度 6-16');
return;
}
login(function() {
window.location.href = 'https://imooc.com';
});
});
</script>
使用这种方式,就可以自主控制流程,不需要再考虑 form 标签的行为。
5. 小结
校验表单非常常见,校验表单的场景很多时候远没有本篇介绍的这么简单,有时候数据校验的格式非常复杂,需要结合正则、校验算法等方式来解决,如严格的身份证验证就需要结合身份证算法。