You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript表单验证后无法重新提交问题咨询

表单验证后无法重新提交的解决方法

问题根源

你的代码存在两个核心问题导致修正错误后无法重新提交:

  1. 状态类管理混乱:showError直接替换父元素类名,showSuccess仅添加成功类,导致字段的错误/成功状态无法被正确覆盖或清除。
  2. 无提交放行逻辑:每次提交都用e.preventDefault()阻止默认行为,哪怕所有字段验证通过,也不会触发表单的真正提交。

修复方案

1. 统一字段状态重置逻辑

修改showError和showSuccess函数,先清除旧状态再添加新状态:

// 显示错误信息
function showError(input, message) {
  const formControl = input.parentElement;
  formControl.classList.remove("success");
  formControl.classList.add("error");
  const small = formControl.querySelector("small");
  small.innerText = message;
}

// 显示成功状态
function showSuccess(input) {
  const formControl = input.parentElement;
  formControl.classList.remove("error");
  formControl.classList.add("success");
}

2. 添加验证通过后的提交放行逻辑

在提交事件中,先执行所有验证,再检查是否存在错误字段,仅当无错误时才允许表单提交:

form.addEventListener("submit", (e) => {
  // 重置所有字段的状态和提示文本
  const allInputs = [P_FirstName, P_LastName, P_Email, P_PhoneNum, ParentID, Password];
  allInputs.forEach(input => {
    const formControl = input.parentElement;
    formControl.classList.remove("error", "success");
    formControl.querySelector("small").innerText = "";
  });

  // 执行所有验证规则
  checkRequired(allInputs);
  checkLength(Password, 8, 25);
  checkFirstName(P_FirstName);
  checkLastName(P_LastName);
  checkEmail(P_Email);
  checkPhoneNumber(P_PhoneNum);
  checkUserName(ParentID);
  checkPassword(Password);

  // 判断是否存在错误字段
  const hasErrors = document.querySelectorAll(".input.error").length > 0;
  if (hasErrors) {
    e.preventDefault(); // 有错误则阻止提交
  } else {
    form.submit(); // 无错误则触发表单提交
  }
});

3. 修正拼写错误

将checkLenghth函数名改为规范的checkLength(不影响功能,但提升代码可读性):

// 检查输入长度
function checkLength(input, min, max) {
  if (input.value.length < min) {
    showError(
      input,
      `${getFieldName(input)} must be at least ${min} characters `
    );
  } else if (input.value.length > max) {
    showError(
      input,
      `${getFieldName(input)} must be less than ${max} characters `
    );
  } else {
    showSuccess(input);
  }
}

完整修改后的代码

JavaScript 部分

const form = document.getElementById("form");
const P_FirstName = document.getElementById("P_FirstName");
const P_LastName = document.getElementById("P_LastName");
const P_Email = document.getElementById("P_Email");
const P_PhoneNum = document.getElementById("P_PhoneNum");
const ParentID = document.getElementById("ParentID");
const Password = document.getElementById("Password");

// 显示错误信息
function showError(input, message) {
  const formControl = input.parentElement;
  formControl.classList.remove("success");
  formControl.classList.add("error");
  const small = formControl.querySelector("small");
  small.innerText = message;
}

// 显示成功状态
function showSuccess(input) {
  const formControl = input.parentElement;
  formControl.classList.remove("error");
  formControl.classList.add("success");
}

// 获取字段名称(首字母大写)
function getFieldName(input) {
  return input.id.charAt(0).toUpperCase() + input.id.slice(1);
}

// 检查必填字段
function checkRequired(inputArr) {
  inputArr.forEach(function(input) {
    if (input.value.trim() === "") {
      showError(input, `الرجاء اكمال المعلومات`);
    } else {
      showSuccess(input);
    }
  });
}

// 检查输入长度
function checkLength(input, min, max) {
  if (input.value.length < min) {
    showError(
      input,
      `${getFieldName(input)} must be at least ${min} characters `
    );
  } else if (input.value.length > max) {
    showError(
      input,
      `${getFieldName(input)} must be less than ${max} characters `
    );
  } else {
    showSuccess(input);
  }
}

// 检查名字格式(仅字母)
function checkFirstName(input) {
  var letters = /^[A-Za-z]+$/;
  var ArabicLetters = /^([\u0600-\u06ff]|[\u0750-\u077f]|[\ufb50-\ufbc1]|[\ufbd3-\ufd3f]|[\ufd50-\ufd8f]|[\ufd92-\ufdc7]|[\ufe70-\ufefc]|[\ufdf0-\ufdfd])*$/g;
  if (input.value.match(letters) || input.value.match(ArabicLetters)) {
    showSuccess(input);
  } else {
    showError(
      input,
      `الاسم الاول يجب ان يتضمن حروف فقط بلا أرقام  `
    );
  }
}

// 检查姓氏格式(仅字母)
function checkLastName(input) {
  var letters = /^[A-Za-z]+$/;
  var ArabicLetters = /^([\u0600-\u06ff]|[\u0750-\u077f]|[\ufb50-\ufbc1]|[\ufbd3-\ufd3f]|[\ufd50-\ufd8f]|[\ufd92-\ufdc7]|[\ufe70-\ufefc]|[\ufdf0-\ufdfd])*$/g;
  if (input.value.match(letters) || input.value.match(ArabicLetters)) {
    showSuccess(input);
  } else {
    showError(
      input,
      `الاسم الاخير يجب ان يتضمن حروف فقط بلا أرقام  `
    );
  }
}

// 检查邮箱格式
function checkEmail(input) {
  var validRegex = new RegExp(/^("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
  if (input.value.match(validRegex)) {
    showSuccess(input);
  } else {
    showError(input, "البريد الالكتروني المدخل غير صحيح");
  }
}

// 检查手机号格式
function checkPhoneNumber(input) {
  var Ph_regex = new RegExp(/^(009665|9665|\+9665|05|5)(5|0|3|6|4|9|1|8|7)([0-9]{7})$/);
  if (input.value.match(Ph_regex)) {
    showSuccess(input);
  } else {
    showError(input, "رقم الهاتف المدخل غير صحيح");
  }
}

// 检查用户名格式
function checkUserName(input) {
  var usernameRegex = /^[a-zA-Z0-9]+$/;
  if (input.value.match(usernameRegex)) {
    showSuccess(input);
  } else {
    showError(input, " اسم المستخدم المدخل غير صحيح");
  }
}

// 检查密码格式
function checkPassword(input) {
  var passw = /^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{6,16}$/;
  if (input.value.match(passw)) {
    showSuccess(input);
  } else {
    showError(input, "يجب ان تحتوي كلمة المرور على احرف كبيرة وصغيرة ، ورقم و رمز واحد على الاقل");
  }
}

// 表单提交事件
form.addEventListener("submit", (e) => {
  // 重置所有字段状态
  const allInputs = [P_FirstName, P_LastName, P_Email, P_PhoneNum, ParentID, Password];
  allInputs.forEach(input => {
    const formControl = input.parentElement;
    formControl.classList.remove("error", "success");
    formControl.querySelector("small").innerText = "";
  });

  // 执行所有验证
  checkRequired(allInputs);
  checkLength(Password, 8, 25);
  checkFirstName(P_FirstName);
  checkLastName(P_LastName);
  checkEmail(P_Email);
  checkPhoneNumber(P_PhoneNum);
  checkUserName(ParentID);
  checkPassword(Password);

  // 判断是否有错误
  const hasErrors = document.querySelectorAll(".input.error").length > 0;
  if (hasErrors) {
    e.preventDefault();
  } else {
    form.submit();
  }
});

HTML 部分(无需修改)

<div>
  <div class="con">
    <h1> إنشاء حساب جديد</h1>
    <form action="" id="form" class="form">

      <div class="input" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label for="P_FirstName">الاسم الاول</label>
        <input type="text" name="P_FirstName" id="P_FirstName" autocomplete="off" />
        <small>Error message</small>
      </div>
      <div class="input" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label for="P_LastName">الاسم الاخير</label>
        <input type="text" name="P_LastName" id="P_LastName" autocomplete="off" />
        <small>Error message</small>
      </div>

      <div class="input" style="display:flex; flex-direction: row; justify-content: center; align-items: center" lang="en">
        <label for="P_Email">البريد الالكتروني</label>
        <input type="text" name="P_Email" id="P_Email" placeholder="user@gmail.com" autocomplete="off" />
        <small>Error message</small>

      </div>

      <div class="input" lang="en" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label for="P_PhoneNum">رقم الهاتف </label>
        <input type="text" name="P_PhoneNum" id="P_PhoneNum" placeholder="05xxxxxxxx" autocomplete="off" />
        <small>Error message</small>
      </div>

      <div class="input" lang="en" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label for="ParentID">اسم المستخدم </label>
        <input type="text" name="ParentID" id="ParentID" autocomplete="off" />
        <small>Error message</small>
      </div>

      <div class="input" lang="en" style="display:flex; flex-direction: row; justify-content: center; align-items: center">
        <label for="Password">كلمة المرور </label>
        <input type="password" name="Password" id="Password" placeholder="********" />
        <small>Error message</small>
      </div>
      <button type="submit">إكمال</button>
    </form>
  </div>
</div>

额外优化建议

可以给输入框添加实时验证事件,用户输入时即时反馈,提升体验:

// 示例:实时验证名字
P_FirstName.addEventListener("input", () => {
  if (P_FirstName.value.trim()) {
    checkFirstName(P_FirstName);
  }
});

内容的提问来源于stack exchange,提问作者Hadeel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 01:52:36