JS實(shí)戰(zhàn)之寫一個(gè)登錄表單驗(yàn)證學(xué)會(huì)判斷輸入合法性
前言
很多新手做網(wǎng)頁(yè)時(shí),會(huì)遇到 “用戶亂輸賬號(hào)密碼就提交” 的問題 —— 比如賬號(hào)沒填、密碼少于 6 位、手機(jī)號(hào)格式不對(duì)。今天用一個(gè) “登錄表單驗(yàn)證” 案例,帶你解決這些問題:案例包含 “賬號(hào)、密碼、手機(jī)號(hào)” 三個(gè)輸入框,提交前會(huì)自動(dòng)判斷輸入是否合法,不合法就顯示提示,合法才允許提交,全程不用后端,純 JS 就能實(shí)現(xiàn),新手也能輕松上手。
先看效果:我們要實(shí)現(xiàn)的登錄表單
表單有三個(gè)輸入項(xiàng)和一個(gè)提交按鈕,交互邏輯如下:
- 未填內(nèi)容點(diǎn)提交:對(duì)應(yīng)輸入框下方顯示 “不能為空” 提示(紅色);
- 密碼少于 6 位:提示 “密碼至少 6 位”;
- 手機(jī)號(hào)格式不對(duì)(不是 11 位數(shù)字):提示 “請(qǐng)輸入正確手機(jī)號(hào)”;
- 所有輸入合法:彈出 “驗(yàn)證通過(guò),準(zhǔn)備提交” 提示,允許后續(xù)提交操作。
完整代碼:HTML+CSS+JS(復(fù)制即運(yùn)行)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JS登錄表單驗(yàn)證</title>
<style>
/* 表單整體樣式:居中、整潔 */
.login-form {
width: 400px;
margin: 80px auto;
padding: 30px;
border: 1px solid #eee;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.05);
}
.form-title {
text-align: center;
color: #333;
margin-bottom: 25px;
}
/* 輸入項(xiàng)容器:上下間距 */
.form-group {
margin-bottom: 20px;
}
/* 標(biāo)簽樣式:固定寬度,對(duì)齊 */
.form-label {
display: inline-block;
width: 80px;
text-align: right;
margin-right: 10px;
color: #666;
font-size: 14px;
}
/* 輸入框樣式:統(tǒng)一大小和邊框 */
.form-input {
width: 220px;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
outline: none;
}
/* 輸入框聚焦時(shí):加藍(lán)色邊框,提示當(dāng)前選中 */
.form-input:focus {
border-color: #2196f3;
box-shadow: 0 0 0 2px rgba(33,150,243,0.1);
}
/* 錯(cuò)誤提示樣式:紅色、小字體、左對(duì)齊 */
.error-tip {
margin-left: 95px;
margin-top: 5px;
color: #dc3545;
font-size: 12px;
height: 16px; /* 固定高度,避免提示顯示時(shí)表單晃動(dòng) */
}
/* 提交按鈕樣式:居中、藍(lán)色、hover反饋 */
.submit-btn {
margin-left: 95px;
padding: 9px 30px;
background-color: #2196f3;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.submit-btn:hover {
background-color: #1976d2;
}
</style>
</head>
<body>
<form class="login-form" id="loginForm">
<h2 class="form-title">用戶登錄</h2>
<!-- 賬號(hào)輸入項(xiàng) -->
<div class="form-group">
<label class="form-label" for="username">賬號(hào):</label>
<input type="text" class="form-input" id="username" name="username" placeholder="請(qǐng)輸入賬號(hào)">
<div class="error-tip" id="usernameTip"></div> <!-- 賬號(hào)錯(cuò)誤提示 -->
</div>
<!-- 密碼輸入項(xiàng) -->
<div class="form-group">
<label class="form-label" for="password">密碼:</label>
<input type="password" class="form-input" id="password" name="password" placeholder="請(qǐng)輸入密碼">
<div class="error-tip" id="passwordTip"></div> <!-- 密碼錯(cuò)誤提示 -->
</div>
<!-- 手機(jī)號(hào)輸入項(xiàng) -->
<div class="form-group">
<label class="form-label" for="phone">手機(jī)號(hào):</label>
<input type="text" class="form-input" id="phone" name="phone" placeholder="請(qǐng)輸入手機(jī)號(hào)">
<div class="error-tip" id="phoneTip"></div> <!-- 手機(jī)號(hào)錯(cuò)誤提示 -->
</div>
<!-- 提交按鈕 -->
<button type="submit" class="submit-btn">登錄</button>
</form>
<script>
// 1. 獲取表單和所有輸入項(xiàng)、提示元素
const loginForm = document.getElementById('loginForm');
const username = document.getElementById('username');
const password = document.getElementById('password');
const phone = document.getElementById('phone');
const usernameTip = document.getElementById('usernameTip');
const passwordTip = document.getElementById('passwordTip');
const phoneTip = document.getElementById('phoneTip');
// 2. 定義“顯示錯(cuò)誤提示”的函數(shù)(復(fù)用邏輯,避免重復(fù)代碼)
function showError(input, tipElem, message) {
tipElem.textContent = message; // 顯示提示文字
input.style.borderColor = '#dc3545'; // 輸入框邊框變紅,視覺提示
}
// 3. 定義“清除錯(cuò)誤提示”的函數(shù)(輸入合法時(shí)調(diào)用)
function clearError(input, tipElem) {
tipElem.textContent = ''; // 清空提示文字
input.style.borderColor = '#ddd'; // 輸入框邊框恢復(fù)默認(rèn)
}
// 4. 定義“驗(yàn)證賬號(hào)”的函數(shù):判斷是否為空
function validateUsername() {
const usernameValue = username.value.trim(); // 去除首尾空格(避免用戶只輸空格)
if (usernameValue === '') {
showError(username, usernameTip, '賬號(hào)不能為空');
return false; // 驗(yàn)證不通過(guò),返回false
} else {
clearError(username, usernameTip);
return true; // 驗(yàn)證通過(guò),返回true
}
}
// 5. 定義“驗(yàn)證密碼”的函數(shù):判斷是否為空+長(zhǎng)度是否≥6位
function validatePassword() {
const passwordValue = password.value.trim();
if (passwordValue === '') {
showError(password, passwordTip, '密碼不能為空');
return false;
} else if (passwordValue.length < 6) {
showError(password, passwordTip, '密碼至少6位');
return false;
} else {
clearError(password, passwordTip);
return true;
}
}
// 6. 定義“驗(yàn)證手機(jī)號(hào)”的函數(shù):用正則判斷格式(11位數(shù)字)
function validatePhone() {
const phoneValue = phone.value.trim();
// 手機(jī)號(hào)正則:以1開頭,后面跟10位數(shù)字(簡(jiǎn)單版,覆蓋大部分場(chǎng)景)
const phoneReg = /^1\d{10}$/;
if (phoneValue === '') {
showError(phone, phoneTip, '手機(jī)號(hào)不能為空');
return false;
} else if (!phoneReg.test(phoneValue)) { // test()判斷值是否符合正則
showError(phone, phoneTip, '請(qǐng)輸入正確手機(jī)號(hào)');
return false;
} else {
clearError(phone, phoneTip);
return true;
}
}
// 7. 給輸入框綁“失去焦點(diǎn)事件”(用戶離開輸入框時(shí),實(shí)時(shí)驗(yàn)證)
username.addEventListener('blur', validateUsername);
password.addEventListener('blur', validatePassword);
phone.addEventListener('blur', validatePhone);
// 8. 給表單綁“提交事件”(點(diǎn)擊登錄按鈕時(shí),整體驗(yàn)證)
loginForm.addEventListener('submit', function(e) {
// 阻止表單默認(rèn)提交行為(避免頁(yè)面刷新,方便前端先驗(yàn)證)
e.preventDefault();
// 調(diào)用所有驗(yàn)證函數(shù),判斷是否全部通過(guò)
const isUsernameValid = validateUsername();
const isPasswordValid = validatePassword();
const isPhoneValid = validatePhone();
// 所有驗(yàn)證都通過(guò)時(shí),執(zhí)行“提交”邏輯(這里用提示模擬,實(shí)際項(xiàng)目可發(fā)請(qǐng)求)
if (isUsernameValid && isPasswordValid && isPhoneValid) {
alert('表單驗(yàn)證通過(guò)!準(zhǔn)備提交數(shù)據(jù)~');
// 實(shí)際項(xiàng)目中,這里可加AJAX請(qǐng)求,把表單數(shù)據(jù)發(fā)給后端
// 比如:fetch('/login', { method: 'POST', body: ... })
}
});
</script>
</body>
</html>關(guān)鍵步驟拆解:核心邏輯一看就懂
表單驗(yàn)證的核心是 “判斷輸入是否符合規(guī)則,再給出反饋”,每個(gè)函數(shù)都圍繞 “驗(yàn)證規(guī)則→提示反饋” 展開,邏輯清晰且可復(fù)用。
步驟 1:封裝 “錯(cuò)誤提示” 函數(shù),避免重復(fù)代碼
新手容易在每個(gè)驗(yàn)證里重復(fù)寫 “改提示文字、變邊框顏色” 的代碼,這里用showError()和clearError()兩個(gè)函數(shù)封裝:
- 驗(yàn)證不通過(guò):調(diào)用
showError(),顯示紅色提示 + 紅色邊框; - 驗(yàn)證通過(guò):調(diào)用
clearError(),清空提示 + 恢復(fù)默認(rèn)邊框;后續(xù)新增輸入項(xiàng)(比如 “郵箱”),直接復(fù)用這兩個(gè)函數(shù)即可,不用重復(fù)寫樣式控制。
步驟 2:按 “輸入項(xiàng)” 拆分驗(yàn)證函數(shù),邏輯更清晰
給每個(gè)輸入項(xiàng)單獨(dú)寫驗(yàn)證函數(shù)(validateUsername()/validatePassword()/validatePhone()),每個(gè)函數(shù)只負(fù)責(zé) “判斷當(dāng)前輸入是否合法”,并返回true/false:
- 賬號(hào):只判斷 “是否為空”(可根據(jù)需求擴(kuò)展,比如 “賬號(hào)只能是字母 / 數(shù)字”);
- 密碼:判斷 “是否為空”+“長(zhǎng)度≥6 位”;
- 手機(jī)號(hào):判斷 “是否為空”+“符合 11 位數(shù)字格式”(用正則實(shí)現(xiàn));這樣拆分后,哪個(gè)輸入項(xiàng)出問題,只需要改對(duì)應(yīng)函數(shù),不會(huì)影響其他邏輯。
步驟 3:用 “正則表達(dá)式” 判斷手機(jī)號(hào)格式
手機(jī)號(hào)驗(yàn)證是表單高頻需求,用正則/^1\d{10}$/能快速判斷格式:
^1:以數(shù)字 1 開頭;\d{10}:后面跟 10 位數(shù)字;$:結(jié)束符(確保整個(gè)輸入都是 11 位數(shù)字,避免 “138001380001” 這種超長(zhǎng)值通過(guò));正則不用死記,常用的(手機(jī)號(hào)、郵箱、身份證)可以直接查資料復(fù)用,重點(diǎn)是學(xué)會(huì)用reg.test(值)判斷是否符合規(guī)則。
步驟 4:綁定 “實(shí)時(shí)驗(yàn)證” 和 “提交驗(yàn)證”,提升體驗(yàn)
- 實(shí)時(shí)驗(yàn)證:給輸入框綁
blur事件(用戶離開輸入框時(shí)觸發(fā)),比如用戶輸完賬號(hào)點(diǎn)到密碼框,立刻驗(yàn)證賬號(hào)是否為空,提前發(fā)現(xiàn)問題; - 提交驗(yàn)證:給表單綁
submit事件,點(diǎn)擊登錄時(shí)先驗(yàn)證所有輸入項(xiàng),全部合法才允許提交,避免 “漏驗(yàn)證”;同時(shí)用e.preventDefault()阻止表單默認(rèn)刷新行為,確保前端驗(yàn)證完再處理后續(xù)邏輯。
新手必避的 3 個(gè) “驗(yàn)證坑”
這些坑是新手做表單驗(yàn)證時(shí)最容易踩的,提前避開能讓驗(yàn)證邏輯更嚴(yán)謹(jǐn)。
坑 1:沒去除輸入的 “首尾空格”,導(dǎo)致 “空值判斷失效”
- 錯(cuò)誤:直接用
username.value === ''判斷,用戶輸入 “”(空格)時(shí),會(huì)認(rèn)為 “不是空值”,繞過(guò)驗(yàn)證; - 正確:用
username.value.trim()去除首尾空格,再判斷是否為空 ——trim()是字符串常用方法,能有效過(guò)濾 “無(wú)效空格”。
坑 2:忘記 “阻止表單默認(rèn)提交”,頁(yè)面直接刷新
- 錯(cuò)誤:沒加
e.preventDefault(),點(diǎn)擊提交按鈕時(shí),表單會(huì)按默認(rèn)行為刷新頁(yè)面,前端驗(yàn)證還沒完成就跳轉(zhuǎn); - 正確:在表單
submit事件里第一行寫e.preventDefault(),先做前端驗(yàn)證,驗(yàn)證通過(guò)后再手動(dòng)處理提交(比如發(fā)請(qǐng)求)。
坑 3:正則表達(dá)式 “太復(fù)雜或太寬松”,導(dǎo)致驗(yàn)證不準(zhǔn)
- 錯(cuò)誤:手機(jī)號(hào)正則寫
/^1\d+$/(只判斷以 1 開頭,后面是數(shù)字),會(huì)允許 “123456” 這種短號(hào)通過(guò);或?qū)懱珡?fù)雜的正則(包含所有手機(jī)號(hào)號(hào)段),新手難以維護(hù); - 正確:新手先用 “簡(jiǎn)單且覆蓋大部分場(chǎng)景” 的正則(比如案例里的
/^1\d{10}$/),滿足基礎(chǔ)需求即可,后續(xù)再根據(jù)實(shí)際場(chǎng)景優(yōu)化(比如添加號(hào)段判斷)。
擴(kuò)展玩法:5 分鐘升級(jí)驗(yàn)證功能
學(xué)會(huì)基礎(chǔ)邏輯后,很容易擴(kuò)展成更實(shí)用的表單,比如:
- 添加 “郵箱驗(yàn)證”:新增郵箱輸入項(xiàng),用正則
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/判斷格式; - 密碼 “強(qiáng)度提示”:輸入密碼時(shí),實(shí)時(shí)提示 “弱 / 中 / 強(qiáng)”(判斷是否包含字母、數(shù)字、特殊符號(hào));
- “重復(fù)密碼” 驗(yàn)證:新增 “重復(fù)密碼” 輸入項(xiàng),判斷和 “密碼” 是否一致,不一致提示 “兩次密碼不相同”;
- 提交按鈕 “加載狀態(tài)”:點(diǎn)擊提交后,按鈕顯示 “登錄中...” 并禁用,避免用戶重復(fù)點(diǎn)擊。
這個(gè) “登錄表單驗(yàn)證” 案例雖然基礎(chǔ),但覆蓋了前端表單的核心需求 —— 實(shí)際項(xiàng)目中,無(wú)論是注冊(cè)、登錄還是信息提交,驗(yàn)證邏輯都和這個(gè)案例相通。新手只要吃透 “拆分驗(yàn)證函數(shù)、封裝復(fù)用邏輯、處理邊界情況” 這三個(gè)點(diǎn),就能輕松應(yīng)對(duì)大部分表單場(chǎng)景。
試試給表單加個(gè) “郵箱驗(yàn)證” 功能吧~ 如果遇到正則或邏輯問題,隨時(shí)可以交流!
到此這篇關(guān)于JS實(shí)戰(zhàn)之寫一個(gè)登錄表單驗(yàn)證學(xué)會(huì)判斷輸入合法性的文章就介紹到這了,更多相關(guān)JS登錄表單驗(yàn)證判斷輸入合法性內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TypeScript 不可變性 readonly, Readonly<T>的使用小結(jié)
TypeScript 作為 JavaScript 的超集,為我們提供了強(qiáng)大的類型系統(tǒng),其中就包括了實(shí)現(xiàn)不可變性的有效工具,今天,我們就來(lái)聊聊如何使用 readonly和 Readonly來(lái)提升代碼的健壯性和可維護(hù)性2026-05-05
JS設(shè)置隨機(jī)出現(xiàn)2個(gè)數(shù)字的實(shí)例代碼
這篇文章給大家分享基于js設(shè)置隨機(jī)出現(xiàn)2個(gè)數(shù)字的實(shí)例代碼,在文章下面給分享js產(chǎn)生隨機(jī)數(shù)的幾個(gè)用法介紹,感興趣的朋友一起看看吧2017-07-07
通過(guò)js修改input、select默認(rèn)字體顏色
這篇文章主要介紹了通過(guò)js修改input、select默認(rèn)字體顏色,需要的朋友可以參考下2017-04-04
uni-app中onBackPress()監(jiān)聽頁(yè)面返回(更新數(shù)據(jù))
這篇文章主要給大家介紹了關(guān)于uni-app中onBackPress()監(jiān)聽頁(yè)面返回(更新數(shù)據(jù))的相關(guān)資料,在UniApp中,可以通過(guò)監(jiān)聽頁(yè)面刷新的生命周期函數(shù)來(lái)監(jiān)聽頁(yè)面的返回,然后重新調(diào)用接口進(jìn)行刷新,需要的朋友可以參考下2023-10-10
基于VSCode調(diào)試網(wǎng)頁(yè)JavaScript代碼過(guò)程詳解
這篇文章主要介紹了基于VSCode調(diào)試網(wǎng)頁(yè)JavaScript代碼過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
JS滾輪控制圖片縮放大小和拖動(dòng)的實(shí)例代碼
本文通過(guò)實(shí)例代碼給大家介紹了js 滾輪控制圖片縮放大小和拖動(dòng),代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-11-11
Javascript 模擬mvc實(shí)現(xiàn)點(diǎn)餐程序案例詳解
這篇文章主要介紹了Javascript 模擬mvc實(shí)現(xiàn)點(diǎn)餐程序案例詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

