JavaScript表单验证实例:正则表达式与输入检查代码

作者:函数茶馆

时间:2026-10-30

浏览:260

详细讲解使用原生JavaScript进行表单验证的实现方案,涵盖常用正则表达式模式、实时与提交时输入检查逻辑及完整代码示例。

文章目录

在前端交互开发中,表单验证是保证数据格式规范、提升填报体验的核心环节。本文直接围绕用户名、手机号、邮箱与密码四类典型字段,给出完整的正则表达式定义、输入检查逻辑以及原生JavaScript驱动的验证实例,帮助读者快速落地健壮的客户端表单校验。

一、表单输入验证的核心处理流程

前端验证并不神秘,其核心逻辑建立在DOM事件监听与正则匹配之上。当用户在输入框中录入信息或点击提交按钮时,脚本通过阻止浏览器默认提交行为,依次提取字段值、运行格式校验规则、渲染错误反馈,并在全部字段通过后才放行请求。

JavaScript表单验证实例:正则表达式与输入检查代码
图1:JavaScript表单输入验证的标准执行步骤

二、常用输入项的正则表达式设计

表单验证的核心在于准确的正则表达式。以下为日常开发中最常用的四组正则规则及说明:

验证字段 正则表达式模式 规则含义与适用边界
用户名 ^[a-zA-Z0-9_]{4,16}$ 允许英文字母、数字和下划线,长度在4到16位之间。
中国大陆手机号 ^1[3-9]\d{9}$ 以数字1开头,第二位为3至9,后接9位纯数字,共11位。
电子邮箱 ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ 匹配标准邮箱用户名、@符号、域名主体与至少2位顶级域。
密码强度 ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d\W_]{8,20}$ 必须包含大小写字母与数字,允许特殊符号,长度8到20位。

三、核心语法与正则匹配机制解析

在编写表单检查代码前,必须掌握正则表达式各组成符号的作用。特别是前瞻断言(Lookahead),常用于在不消耗字符的情况下,同时判断多项复杂密码规则。

JavaScript表单验证实例:正则表达式与输入检查代码
图2:复杂正则表达式构成要素分解图

四、验证时机对比:实时验证 vs 提交时验证

验证时机的选择直接决定了用户的交互体验。常见的验证时机有两种:一是在用户操作过程中触发(实时/失焦验证),二是表单提交时统一校验。二者在触发条件、性能开销以及交互反馈上存在明确差异:

JavaScript表单验证实例:正则表达式与输入检查代码
图3:两种常见表单验证触发时机的特点对比

在实际生产环境中,最佳实践通常是二者结合:在字段失焦(blur)时检查单个输入项并给予提示;而在表单提交(submit)时做整体扫描,拦截不合法状态。

五、完整的表单结构与JavaScript验证代码

下面给出一段开箱即用的完整示例,包含HTML表单、内联状态控制样式以及对应的JavaScript模块化验证代码。

1. HTML 与样式结构

<form id="registerForm" novalidate>
  <div class="form-group">
    <label for="username">用户名</label>
    <input type="text" id="username" placeholder="4-16位字母、数字或下划线" />
    <span class="error-tip" id="usernameError"></span>
  </div>

  <div class="form-group">
    <label for="phone">手机号</label>
    <input type="tel" id="phone" placeholder="11位手机号码" />
    <span class="error-tip" id="phoneError"></span>
  </div>

  <div class="form-group">
    <label for="email">电子邮箱</label>
    <input type="email" id="email" placeholder="example@domain.com" />
    <span class="error-tip" id="emailError"></span>
  </div>

  <div class="form-group">
    <label for="password">密码</label>
    <input type="password" id="password" placeholder="8-20位,含大小写字母与数字" />
    <span class="error-tip" id="passwordError"></span>
  </div>

  <button type="submit" id="submitBtn">立即注册</button>
</form>

注意:表单标签中添加 novalidate 属性是为了关闭浏览器自带的简易校验气泡,确保由我们自定义的JavaScript规则完全接管提示与校验样式。

2. 原生 JavaScript 验证脚本

// 规则定义字典:聚合字段正则与对应错误提示
const validationRules = {
  username: {
    pattern: /^[a-zA-Z0-9_]{4,16}$/,
    emptyMsg: '用户名不能为空',
    invalidMsg: '用户名须为4-16位字母、数字或下划线'
  },
  phone: {
    pattern: /^1[3-9]\d{9}$/,
    emptyMsg: '手机号码不能为空',
    invalidMsg: '请输入正确的11位中国大陆手机号'
  },
  email: {
    pattern: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
    emptyMsg: '电子邮箱不能为空',
    invalidMsg: '请输入有效的邮箱地址'
  },
  password: {
    pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d\W_]{8,20}$/,
    emptyMsg: '密码不能为空',
    invalidMsg: '密码长度需8-20位,且包含大小写字母与数字'
  }
};

/**
 * 校验指定输入框的值是否合法
 * @param {HTMLInputElement} inputEl 输入元素
 * @returns {boolean} 是否通过验证
 */
function validateField(inputEl) {
  const fieldName = inputEl.id;
  const rule = validationRules[fieldName];
  const errorEl = document.getElementById(fieldName + 'Error');
  if (!rule || !errorEl) return true;

  const value = inputEl.value.trim();

  // 1. 空值检查
  if (value === '') {
    errorEl.textContent = rule.emptyMsg;
    inputEl.classList.add('is-invalid');
    return false;
  }

  // 2. 正则格式匹配
  if (!rule.pattern.test(value)) {
    errorEl.textContent = rule.invalidMsg;
    inputEl.classList.add('is-invalid');
    return false;
  }

  // 3. 校验通过,清除错误信息与高亮
  errorEl.textContent = '';
  inputEl.classList.remove('is-invalid');
  return true;
}

// 获取表单与输入项
const form = document.getElementById('registerForm');
const fields = ['username', 'phone', 'email', 'password'].map(id => document.getElementById(id));

// 绑定失焦 (blur) 实时检查
fields.forEach(inputEl => {
  if (inputEl) {
    inputEl.addEventListener('blur', () => {
      validateField(inputEl);
    });
    // 当用户重新输入时,立即移除错误样式
    inputEl.addEventListener('input', () => {
      const errorEl = document.getElementById(inputEl.id + 'Error');
      if (errorEl) errorEl.textContent = '';
      inputEl.classList.remove('is-invalid');
    });
  }
});

// 绑定提交 (submit) 全局验证
form.addEventListener('submit', (event) => {
  event.preventDefault(); // 阻止默认表单提交

  let isFormValid = true;

  // 依次校验所有字段
  fields.forEach(inputEl => {
    const valid = validateField(inputEl);
    if (!valid) {
      isFormValid = false;
    }
  });

  if (!isFormValid) {
    console.warn('表单存在验证错误,已拦截提交');
    return;
  }

  // 全部通过后的业务处理(如发送 fetch 请求)
  console.log('表单验证全部通过,准备提交数据!');
  const formData = {
    username: fields[0].value.trim(),
    phone: fields[1].value.trim(),
    email: fields[2].value.trim(),
    password: fields[3].value
  };
  // 发送请求示例:fetch('/api/register', { method: 'POST', body: JSON.stringify(formData) })
});

六、验证与异常处理注意事项

在实际落地表单验证代码时,开发人员常常因为忽略细节边界而导致意外漏洞,以下三点需要特别重视:

  • 前端验证不能替代后端校验:前端JavaScript处于客户端控制下,恶意用户可以直接通过控制台修改代码或直接调用接口发起请求。因此,前端验证的目的主要是提升交互体验和拦截无效输入,后端服务器依然必须执行等同或更严格的格式与安全性校验。
  • 避免 test() 与全局修饰符 g 混用:如果在正则字面量上添加了全局匹配标识符 /g,JavaScript 的 RegExp 实例会维护一个名为 lastIndex 的指针。多次调用 regex.test(str) 时会导致即使相同的内容交替出现 true 和 false 的致命隐患。因此,表单验证正则严禁携带 g 标志。
  • 字符串清洗与前后空格处理:用户通过手机键盘或复制粘贴输入时,常常会无意中夹带前导或尾随空格。在调用 test() 之前,应当先通过 value.trim() 清理多余空格,确保正则匹配结果的客观准确。
JavaScript表单验证实例:正则表达式与输入检查代码
图4:表单验证工程实践关键要点总结

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章