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

如何检测DOM元素上reportValidity()是否正在显示validityMessage?

解决Safari中重复调用reportValidity()导致验证消息切换的问题

核心问题

在Safari中,重复调用reportValidity()会切换验证消息的显示/隐藏状态,而Firefox无此行为。当提交无效表单时,form.reportValidity()会自动聚焦到第一个无效输入框,触发输入框的focus事件;若此时focus事件中也调用了input.reportValidity(),就会在Safari中导致刚显示的验证消息被隐藏。

浏览器目前没有提供公开接口直接检测验证消息的显示状态,因此需要通过控制reportValidity()的调用时机来规避跨浏览器差异。

解决方案

通过临时标志区分「表单提交导致的聚焦」和「用户手动触发的聚焦」,避免在提交流程中重复调用reportValidity():

修改后的代码示例

HTML

<form action="#" id="form">
  <input type="number" max="5" value="10" name="invalid" id="invalid" autocomplete="off">
  <input type="submit" value="validate">
</form>

JavaScript

const input = document.getElementById("invalid");
const form = document.getElementById("form");
// 标记是否为表单提交导致的聚焦
let isSubmitting = false;

input.addEventListener("focus", () => {
  // 仅当非提交触发的聚焦、且输入框确实无效时,才显示验证消息
  if (!isSubmitting && !input.checkValidity()) {
    input.reportValidity();
  }
});

form.addEventListener("submit", (e) => {
  e.preventDefault();
  isSubmitting = true;
  form.reportValidity();
  // 延迟清除标志,确保浏览器完成聚焦后不影响后续手动操作
  setTimeout(() => {
    isSubmitting = false;
  }, 100);
});

原理说明

  1. 表单提交时先设置isSubmitting为true,再触发表单验证;
  2. 浏览器自动聚焦到无效输入框时,focus事件因检测到isSubmitting为true,跳过reportValidity()调用,避免Safari中消息被隐藏;
  3. 用setTimeout延迟清除标志,确保用户后续手动聚焦输入框时,依然能正常触发验证消息;
  4. 加入input.checkValidity()判断,确保只有输入框确实无效时才调用验证方法,避免无意义的执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:46:18