Skip to content

表单验证(实战必备)

16.1 表单元素获取

在进行表单验证之前,我们需要先获取表单元素。

获取表单元素

javascript
// 获取表单
const form = document.getElementById("myForm");

// 获取输入框
const username = document.getElementById("username");
const email = document.getElementById("email");
const password = document.getElementById("password");

// 获取单选按钮
const genderMale = document.getElementById("gender-male");
const genderFemale = document.getElementById("gender-female");

// 获取复选框
const agree = document.getElementById("agree");

// 获取下拉菜单
const country = document.getElementById("country");

获取表单值

javascript
// 获取输入框值
const usernameValue = username.value;
const emailValue = email.value;
const passwordValue = password.value;

// 获取单选按钮值
let genderValue;
if (genderMale.checked) {
  genderValue = genderMale.value;
} else if (genderFemale.checked) {
  genderValue = genderFemale.value;
}

// 获取复选框状态
const agreeValue = agree.checked;

// 获取下拉菜单值
const countryValue = country.value;

16.2 输入框非空验证

非空验证是最基本的表单验证,确保用户填写了必要的信息。

实现非空验证

javascript
function validateRequired(input, errorMessage) {
  const value = input.value.trim();
  if (value === "") {
    // 显示错误信息
    showError(input, errorMessage);
    return false;
  } else {
    // 清除错误信息
    clearError(input);
    return true;
  }
}

function showError(input, message) {
  // 获取输入框的父元素
  const formControl = input.parentElement;
  
  // 查找错误信息元素
  let errorElement = formControl.querySelector(".error");
  
  // 如果没有错误信息元素,创建一个
  if (!errorElement) {
    errorElement = document.createElement("div");
    errorElement.className = "error";
    formControl.appendChild(errorElement);
  }
  
  // 设置错误信息
  errorElement.textContent = message;
  
  // 添加错误样式
  formControl.classList.add("error");
}

function clearError(input) {
  const formControl = input.parentElement;
  const errorElement = formControl.querySelector(".error");
  
  if (errorElement) {
    errorElement.textContent = "";
  }
  
  formControl.classList.remove("error");
}

16.3 手机号 / 邮箱格式验证

手机号格式验证

javascript
function validatePhone(phone) {
  const phoneRegex = /^1[3-9]\d{9}$/;
  if (!phoneRegex.test(phone.value.trim())) {
    showError(phone, "请输入有效的手机号码");
    return false;
  } else {
    clearError(phone);
    return true;
  }
}

邮箱格式验证

javascript
function validateEmail(email) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(email.value.trim())) {
    showError(email, "请输入有效的邮箱地址");
    return false;
  } else {
    clearError(email);
    return true;
  }
}

密码强度验证

javascript
function validatePassword(password) {
  const passwordValue = password.value;
  
  // 密码长度至少8位
  if (passwordValue.length < 8) {
    showError(password, "密码长度至少8位");
    return false;
  }
  
  // 密码包含至少一个数字
  if (!/\d/.test(passwordValue)) {
    showError(password, "密码至少包含一个数字");
    return false;
  }
  
  // 密码包含至少一个字母
  if (!/[a-zA-Z]/.test(passwordValue)) {
    showError(password, "密码至少包含一个字母");
    return false;
  }
  
  clearError(password);
  return true;
}

16.4 表单提交阻止默认行为

在表单验证中,我们通常需要阻止表单的默认提交行为,以便在验证通过后再提交。

javascript
const form = document.getElementById("myForm");

form.addEventListener("submit", function(event) {
  // 阻止默认提交行为
  event.preventDefault();
  
  // 执行表单验证
  const isUsernameValid = validateRequired(username, "请输入用户名");
  const isEmailValid = validateEmail(email);
  const isPasswordValid = validatePassword(password);
  const isAgreeValid = validateRequired(agree, "请同意用户协议");
  
  // 如果所有验证都通过,提交表单
  if (isUsernameValid && isEmailValid && isPasswordValid && isAgreeValid) {
    // 可以在这里使用 AJAX 提交表单,或者手动提交
    console.log("表单验证通过,准备提交");
    // form.submit(); // 手动提交表单
  }
});

16.5 实战:注册表单验证

完整的注册表单验证示例

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>注册表单验证</title>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body {
      font-family: Arial, sans-serif;
      background-color: #f4f4f4;
      padding: 20px;
    }
    
    .container {
      max-width: 600px;
      margin: 0 auto;
      background-color: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    }
    
    h2 {
      text-align: center;
      margin-bottom: 20px;
      color: #333;
    }
    
    .form-group {
      margin-bottom: 15px;
    }
    
    label {
      display: block;
      margin-bottom: 5px;
      font-weight: bold;
      color: #555;
    }
    
    input[type="text"],
    input[type="email"],
    input[type="password"],
    select {
      width: 100%;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      font-size: 16px;
    }
    
    input[type="radio"],
    input[type="checkbox"] {
      margin-right: 5px;
    }
    
    .radio-group {
      display: flex;
      gap: 20px;
    }
    
    .error {
      color: #ff4444;
      font-size: 12px;
      margin-top: 5px;
    }
    
    .form-group.error input {
      border-color: #ff4444;
    }
    
    button {
      width: 100%;
      padding: 12px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      font-size: 16px;
      cursor: pointer;
      margin-top: 10px;
    }
    
    button:hover {
      background-color: #45a049;
    }
  </style>
</head>
<body>
  <div class="container">
    <h2>用户注册</h2>
    <form id="registerForm">
      <div class="form-group">
        <label for="username">用户名</label>
        <input type="text" id="username" name="username" placeholder="请输入用户名">
      </div>
      
      <div class="form-group">
        <label for="email">邮箱</label>
        <input type="email" id="email" name="email" placeholder="请输入邮箱">
      </div>
      
      <div class="form-group">
        <label for="password">密码</label>
        <input type="password" id="password" name="password" placeholder="请输入密码">
      </div>
      
      <div class="form-group">
        <label for="confirmPassword">确认密码</label>
        <input type="password" id="confirmPassword" name="confirmPassword" placeholder="请确认密码">
      </div>
      
      <div class="form-group">
        <label>性别</label>
        <div class="radio-group">
          <label><input type="radio" name="gender" value="male"> 男</label>
          <label><input type="radio" name="gender" value="female"> 女</label>
        </div>
      </div>
      
      <div class="form-group">
        <label for="country">国家/地区</label>
        <select id="country" name="country">
          <option value="">请选择</option>
          <option value="china">中国</option>
          <option value="usa">美国</option>
          <option value="japan">日本</option>
          <option value="other">其他</option>
        </select>
      </div>
      
      <div class="form-group">
        <label><input type="checkbox" id="agree" name="agree"> 我同意用户协议和隐私政策</label>
      </div>
      
      <button type="submit">注册</button>
    </form>
  </div>

  <script>
    // 获取表单元素
    const form = document.getElementById("registerForm");
    const username = document.getElementById("username");
    const email = document.getElementById("email");
    const password = document.getElementById("password");
    const confirmPassword = document.getElementById("confirmPassword");
    const gender = document.getElementsByName("gender");
    const country = document.getElementById("country");
    const agree = document.getElementById("agree");

    // 显示错误信息
    function showError(input, message) {
      const formGroup = input.parentElement;
      let errorElement = formGroup.querySelector(".error");
      
      if (!errorElement) {
        errorElement = document.createElement("div");
        errorElement.className = "error";
        formGroup.appendChild(errorElement);
      }
      
      errorElement.textContent = message;
      formGroup.classList.add("error");
    }

    // 清除错误信息
    function clearError(input) {
      const formGroup = input.parentElement;
      const errorElement = formGroup.querySelector(".error");
      
      if (errorElement) {
        errorElement.textContent = "";
      }
      
      formGroup.classList.remove("error");
    }

    // 非空验证
    function validateRequired(input, message) {
      const value = input.value.trim();
      if (value === "") {
        showError(input, message);
        return false;
      } else {
        clearError(input);
        return true;
      }
    }

    // 邮箱验证
    function validateEmail(input) {
      const value = input.value.trim();
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      
      if (value === "") {
        showError(input, "请输入邮箱");
        return false;
      } else if (!emailRegex.test(value)) {
        showError(input, "请输入有效的邮箱地址");
        return false;
      } else {
        clearError(input);
        return true;
      }
    }

    // 密码验证
    function validatePassword(input) {
      const value = input.value;
      
      if (value === "") {
        showError(input, "请输入密码");
        return false;
      } else if (value.length < 8) {
        showError(input, "密码长度至少8位");
        return false;
      } else if (!/\d/.test(value)) {
        showError(input, "密码至少包含一个数字");
        return false;
      } else if (!/[a-zA-Z]/.test(value)) {
        showError(input, "密码至少包含一个字母");
        return false;
      } else {
        clearError(input);
        return true;
      }
    }

    // 确认密码验证
    function validateConfirmPassword(input) {
      const value = input.value;
      const passwordValue = password.value;
      
      if (value === "") {
        showError(input, "请确认密码");
        return false;
      } else if (value !== passwordValue) {
        showError(input, "两次输入的密码不一致");
        return false;
      } else {
        clearError(input);
        return true;
      }
    }

    // 性别验证
    function validateGender() {
      let isSelected = false;
      for (let i = 0; i < gender.length; i++) {
        if (gender[i].checked) {
          isSelected = true;
          break;
        }
      }
      
      const formGroup = gender[0].parentElement.parentElement;
      let errorElement = formGroup.querySelector(".error");
      
      if (!isSelected) {
        if (!errorElement) {
          errorElement = document.createElement("div");
          errorElement.className = "error";
          formGroup.appendChild(errorElement);
        }
        errorElement.textContent = "请选择性别";
        formGroup.classList.add("error");
        return false;
      } else {
        if (errorElement) {
          errorElement.textContent = "";
        }
        formGroup.classList.remove("error");
        return true;
      }
    }

    // 国家验证
    function validateCountry(input) {
      if (input.value === "") {
        showError(input, "请选择国家/地区");
        return false;
      } else {
        clearError(input);
        return true;
      }
    }

    // 协议验证
    function validateAgree(input) {
      if (!input.checked) {
        const formGroup = input.parentElement;
        let errorElement = formGroup.querySelector(".error");
        
        if (!errorElement) {
          errorElement = document.createElement("div");
          errorElement.className = "error";
          formGroup.appendChild(errorElement);
        }
        
        errorElement.textContent = "请同意用户协议和隐私政策";
        formGroup.classList.add("error");
        return false;
      } else {
        const formGroup = input.parentElement;
        const errorElement = formGroup.querySelector(".error");
        
        if (errorElement) {
          errorElement.textContent = "";
        }
        formGroup.classList.remove("error");
        return true;
      }
    }

    // 表单提交事件
    form.addEventListener("submit", function(event) {
      event.preventDefault();
      
      // 执行所有验证
      const isUsernameValid = validateRequired(username, "请输入用户名");
      const isEmailValid = validateEmail(email);
      const isPasswordValid = validatePassword(password);
      const isConfirmPasswordValid = validateConfirmPassword(confirmPassword);
      const isGenderValid = validateGender();
      const isCountryValid = validateCountry(country);
      const isAgreeValid = validateAgree(agree);
      
      // 如果所有验证都通过
      if (isUsernameValid && isEmailValid && isPasswordValid && 
          isConfirmPasswordValid && isGenderValid && isCountryValid && isAgreeValid) {
        // 模拟表单提交
        console.log("表单验证通过,准备提交");
        alert("注册成功!");
        form.reset();
      }
    });

    // 实时验证
    username.addEventListener("blur", function() {
      validateRequired(username, "请输入用户名");
    });

    email.addEventListener("blur", function() {
      validateEmail(email);
    });

    password.addEventListener("blur", function() {
      validatePassword(password);
    });

    confirmPassword.addEventListener("blur", function() {
      validateConfirmPassword(confirmPassword);
    });

    country.addEventListener("blur", function() {
      validateCountry(country);
    });

    agree.addEventListener("change", function() {
      validateAgree(agree);
    });
  </script>
</body>
</html>

小结

  • 表单验证是确保用户输入数据正确性的重要手段
  • 常用的验证类型:
    • 非空验证:确保必填字段已填写
    • 格式验证:确保输入符合特定格式(如手机号、邮箱)
    • 长度验证:确保输入长度符合要求
    • 一致性验证:确保两次输入一致(如密码确认)
    • 选择验证:确保用户选择了选项(如性别、协议)
  • 使用 event.preventDefault() 阻止表单默认提交行为
  • 实时验证可以提升用户体验,在用户输入过程中或失去焦点时进行验证
  • 错误信息应该清晰明确,帮助用户快速修正错误
  • 完整的表单验证可以防止无效数据提交到服务器,减轻服务器负担

© 2026 编程马·菜鸟教程 版权所有