【问题标题】:Why is setCustomValidity('') ignored on input (Chrome 65)为什么 setCustomValidity('') 在输入时被忽略(Chrome 65)
【发布时间】:2018-09-18 07:28:16
【问题描述】:

注意:据我所知,这个问题不是以下问题的重复问题:


概述

给定一个字段:

  • 为验证设置了pattern 属性,例如"[a-f,0-9]{4}" 用于4 个字符的十六进制字符串输入。
  • 已将oninvalid 设置为setCustomValidity('...some message...') 以定义自定义验证消息
  • 已将oninput 设置为setCustomValidity('') 以重置输入

下面是一个例子:

/* jshint esnext: true */
const form   = document.querySelector("#form");
const field  = document.querySelector("#field");
const output = document.querySelector("#output");

form.addEventListener('submit', (e) => {
  console.log("SUBMIT");
  output.textContent = field.value;
  e.preventDefault(); // Prevent default POST request
});

field.oninvalid = (event) => {
  console.log("INVALID");
  event.target.setCustomValidity('must be valid 4 hex characters');
}

field.oninput = (event) => {
  console.log("INPUT");
  event.target.setCustomValidity('');
}
Output: <span id="output">No output</span>
<form id="form">
  <label for="field">Enter 4 character hex code: </label>
  <input id="field" type="text" pattern="[a-f,0-9]{4}" autocomplete=off>
</form>

验证几乎可以按预期进行,除非用户输入了无效条目,然后继续尝试编辑它,此时他们的以下输入状态仍然无效:

此时,既没有使用oninvalid中定义的自定义setCustomValidity消息,也没有使用onInput中定义的空消息。

相反,只要该字段处于无效状态且未模糊,就会出现默认的Please match the requested format. 消息。


问题

这里发生了什么?看控制台,每次调用oninput事件,所以每次调用event.target.setCustomValidity('');

那么为什么我们仍然看到通用的默认验证消息? setCustomValidity('') 不应该禁用它吗?

此处可接受的答案应显示以下内容:

  • parameter 字段在验证时受到尊重。
  • 当且仅当用户尝试提交无效字段时才会出现任何验证消息,而不是在他们随后立即修改输入时出现。
  • 默认的Please match the requested format. 消息根本不会出现。

【问题讨论】:

  • 你用的是什么浏览器?我已经在 Mac 上的 Chrome 和 Safari 中测试了您的 Bin,但无法在 GIF 动画中重现该问题。只有当输入无效时才会显示正确的消息
  • Windows 上的 Chrome:Version 65.0.3325.181 (Official Build) (64-bit)。这是一个错误的可能性吗?
  • 似乎是这样,尽管他们的问题略有不同,因为他们推荐的解决方法(使用此模式属性)是我已经在做的事情。不同的用例,但可能相关。
  • 早在 Windows 上使用 Chrome 时,如果没有 title 属性,自定义验证消息将不会显示。如果您不知道,您可以在某些浏览器中为您的自定义消息“命名”。尝试在输入中添加标题,看看是否会改变。

标签: javascript html google-chrome validation input


【解决方案1】:

这似乎是 Windows 中 Chrome 65 的一个错误。

oninput 中使用setCustomValidity('') 应该禁用出现在输入上的默认验证消息。

以下解决方法对我有用:

/* jshint esnext: true */
const form   = document.querySelector("#form");
const field  = document.querySelector("#field");
const output = document.querySelector("#output");

const pattern = field.getAttribute("pattern");

form.addEventListener('submit', (e) => {
  console.log("SUBMIT");
  output.textContent = `User submitted: ${field.value}`;
  e.preventDefault(); // Prevent default POST request
});

field.oninvalid = (event) => {
  console.log("INVALID");
  event.target.setCustomValidity('must be valid 4 hex characters');
}

field.oninput = (event) => {
  console.log("INPUT");
  event.target.setCustomValidity('');
  event.target.removeAttribute("pattern");
}

field.onchange = (event) => {
  console.log("CHANGE");
  event.target.setAttribute("pattern", pattern);
}
  Output: <span id="output">No output</span>
  <form id="form">
    <label for="field">Enter 4 character hex code: </label>
    <input id="field" type="text" pattern="[a-f,0-9]{4}" autocomplete=off>
  </form>

【讨论】:

    【解决方案2】:

    setCustomValidity 用于多个输入组合无效时使用。这就是为什么之后必须手动将其重置为空字符串的原因。否则应该使用 title 属性。

    在编辑输入后试图隐藏验证错误是可以理解的,但这违反了 HTML5 表单理念。只要输入无效,它就会显示出来。

    添加 maxlength 可以帮助用户不超过上限。

    如果您真的希望满足您的要点,请随意不使用 HTML5 表单验证,而是使用自定义的东西。

    因此,即使 setCustomValidity 设置为空字符串,也会显示工具提示的原因是,根据模式属性,输入元素仍然无效。

    <form id="form">
      <label for="field">Enter 4 character hex code: </label>
      <input id="field" type="text" pattern="[a-f,0-9]{4}" maxlength="4" minlength="4" autocomplete="off" title="must be valid 4 hex characters">
    </form>
    

    JS

    const form   = document.querySelector("#form");
    const field  = document.querySelector("#field");
    const output = document.querySelector("#output");
    
    form.addEventListener('submit', (e) => {
      console.log("SUBMIT");
      output.textContent = field.value;
      e.preventDefault(); // Prevent default POST request
    });
    
    field.oninvalid = (event) => {
      console.log("INVALID");
    }
    
    field.oninput = (event) => {
      console.log("INPUT");
    }
    

    【讨论】:

      猜你喜欢
      • 2021-04-16
      • 2021-11-06
      • 2019-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多