为什么在输入时忽略了setCustomValidity('')(Chrome 65)

时间:2018-04-08 23:25:23

标签: javascript html5 google-chrome validation input

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

概述

给出一个字段:

  • 为验证设置了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>
&#13;
&#13;
&#13;

验证几乎按照需要工作,除非用户输入无效条目然后继续尝试编辑它,其后的输入状态仍然无效:

enter image description here

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

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

问题

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

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

这里可接受的答案应该表现如下:

  • 尊重parameter字段以进行验证。
  • 当且仅当用户尝试提交无效字段而不是之后立即修改输入时,才会显示任何验证消息。
  • 默认Please match the requested format.消息根本不会出现。

2 个答案:

答案 0 :(得分:3)

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

setCustomValidity('')中使用oninput会禁用输入中显示的默认验证消息。

以下解决方法适用于我:

/* 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>

答案 1 :(得分:0)

当多个输入组合无效时,将使用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");
}