Skip to content
Go back

html` setCustomValidity() `方法添加自定义表单验证

Table of contents

Open Table of contents

📋 方法概述

setCustomValidity() 是 HTML5 表单验证 API 的一部分,它允许开发者为表单元素设置自定义验证消息。

// 基本用法
element.setCustomValidity(message);

🔧 工作原理

💡 核心特性

1. 与 HTML5 验证协同工作

2. 验证时机

🚀 基本使用示例

示例 1:密码确认验证

<form id="signup-form">
  <input type="password" id="password" placeholder="密码" required />
  <input
    type="password"
    id="confirm-password"
    placeholder="确认密码"
    required
  />
  <button type="submit">注册</button>
</form>

<script>
  const password = document.getElementById("password");
  const confirmPassword = document.getElementById("confirm-password");

  function validatePassword() {
    if (password.value !== confirmPassword.value) {
      confirmPassword.setCustomValidity("两次输入的密码不一致");
    } else {
      confirmPassword.setCustomValidity("");
    }
  }

  password.addEventListener("input", validatePassword);
  confirmPassword.addEventListener("input", validatePassword);
</script>

示例 2:自定义格式验证

<form id="order-form">
  <input type="text" id="promo-code" placeholder="优惠码" />
  <span id="promo-hint">提示:优惠码格式为 DISCOUNT-2023</span>
  <button type="submit">提交订单</button>
</form>

<script>
  const promoCode = document.getElementById("promo-code");

  promoCode.addEventListener("input", function () {
    const pattern = /^DISCOUNT-\d{4}$/;

    if (this.value && !pattern.test(this.value)) {
      this.setCustomValidity("优惠码格式不正确,应为 DISCOUNT-年份");
    } else {
      this.setCustomValidity("");
    }
  });
</script>

🎨 高级用法

1. 实时反馈与样式控制

function validateWithFeedback(element, isValid, message) {
  if (!isValid) {
    element.setCustomValidity(message);
    element.classList.add('invalid');
    element.classList.remove('valid');
  } else {
    element.setCustomValidity('');
    element.classList.add('valid');
    element.classList.remove('invalid');
  }
}

// 添加对应的 CSS
.invalid {
  border-color: #e74c3c;
  box-shadow: 0 0 5px rgba(231, 76, 60, 0.5);
}

.valid {
  border-color: #2ecc71;
}

2. 复杂业务逻辑验证

// 验证年龄和会员资格
function validateMembership() {
  const age = document.getElementById("age");
  const isPremium = document.getElementById("premium").checked;

  if (isPremium && age.value < 18) {
    age.setCustomValidity("未满18岁不能注册高级会员");
    return false;
  }

  age.setCustomValidity("");
  return true;
}

// 验证多个字段的依赖关系
function validateDependentFields() {
  const delivery = document.getElementById("delivery-method");
  const address = document.getElementById("address");

  if (delivery.value === "express" && !address.value.trim()) {
    address.setCustomValidity("选择加急配送必须填写详细地址");
    return false;
  }

  address.setCustomValidity("");
  return true;
}

📝 实用技巧

1. 重置表单时清除验证

document.querySelector("form").addEventListener("reset", function () {
  this.querySelectorAll("input").forEach(input => {
    input.setCustomValidity("");
  });
});

2. 检查验证状态

function getValidationStatus() {
  const elements = document.querySelectorAll("input, select, textarea");
  const invalidElements = [];

  elements.forEach(element => {
    if (!element.validity.valid) {
      invalidElements.push({
        element,
        message: element.validationMessage,
      });
    }
  });

  return invalidElements;
}

3. 结合 Constraint Validation API

function getValidityDetails(element) {
  return {
    valid: element.validity.valid,
    valueMissing: element.validity.valueMissing,
    typeMismatch: element.validity.typeMismatch,
    patternMismatch: element.validity.patternMismatch,
    tooLong: element.validity.tooLong,
    tooShort: element.validity.tooShort,
    rangeUnderflow: element.validity.rangeUnderflow,
    rangeOverflow: element.validity.rangeOverflow,
    stepMismatch: element.validity.stepMismatch,
    badInput: element.validity.badInput,
    customError: element.validity.customError,
    message: element.validationMessage,
  };
}

⚠️ 注意事项

  1. 兼容性:现代浏览器普遍支持 无需考虑兼容性

  2. 表单提交行为:设置自定义验证会阻止表单提交

    form.addEventListener("submit", function (event) {
      if (!this.checkValidity()) {
        event.preventDefault();
        // 显示所有错误信息
      }
    });

🔄 替代方案比较

方法优点缺点
setCustomValidity()原生支持、与表单API集成好样式控制有限
JavaScript 验证库功能强大、样式丰富增加包体积
自定义验证逻辑完全控制需要手动实现所有功能


Share this post on:

Previous Post
使用html元素为长 URL 实现清晰的换行符
Next Post
以往博客文章汇总