Примечание: насколько мне известно, этот вопрос является нет дублирующим вопросом следующего:
Учитывая поле, которое:
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.info("SUBMIT");
output.textContent = field.value;
e.preventDefault(); // Prevent default POST request
});
field.oninvalid = (event) => {
console.info("INVALID");
event.target.setCustomValidity('must be valid 4 hex characters');
}
field.oninput = (event) => {
console.info("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>Проверка работает почти так, как хотелось бы, за исключением случаев, когда пользователь вводит недопустимую запись, а затем пытается ее отредактировать, при этом следующие состояния ввода все еще недействительны:
На этом этапе не используется ни пользовательское сообщение setCustomValidity, определенное в oninvalid, ни пустое сообщение, определенное в onInput.
Вместо этого, пока поле находится в недопустимом состоянии и не размыто, отображается сообщение Please match the requested format. по умолчанию.
Что здесь происходит? Глядя на консоль, каждый раз вызывается событие oninput, и поэтому каждый раз вызывается event.target.setCustomValidity('');.
Так почему же мы все еще видим общее сообщение проверки по умолчанию? Разве setCustomValidity('') не должен это отключать?
Приемлемый ответ здесь должен показывать следующее:
parameter используется для проверки.Please match the requested format. по умолчанию никогда не появляется.Chrome в Windows: Version 65.0.3325.181 (Official Build) (64-bit). Вероятность того, что это ошибка?
Ага. Связанный? stackoverflow.com/questions/49646085/…
Похоже, что это так, хотя их проблема немного отличается, поскольку их рекомендуемый обходной путь (с использованием этого атрибута шаблона) - это то, что я уже делаю. Другой вариант использования, но, вероятно, связанный.
Было время, когда Chrome в Windows работал рано, когда пользовательское сообщение проверки не отображалось без атрибута title. Если вы не знаете, вы можете «назвать» свое собственное сообщение в некоторых браузерах. Попробуйте добавить заголовок к вводу и посмотрите, изменится ли это.
Интересно. Он добавляет заголовок под сообщением по умолчанию всякий раз, когда он его показывает. Не то, что мне здесь нужно, но полезно знать!
Да ... сообщите об ошибке или выполните резервное копирование браузера.
Выяснил обходной путь. удаление атрибута pattern в oninput и повторное добавление его в onchange дает мне желаемое поведение.
Рад, что ты разобрался! Потрясающие.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже, что это ошибка Chrome 65 в Windows.
использование 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.info("SUBMIT");
output.textContent = `User submitted: ${field.value}`;
e.preventDefault(); // Prevent default POST request
});
field.oninvalid = (event) => {
console.info("INVALID");
event.target.setCustomValidity('must be valid 4 hex characters');
}
field.oninput = (event) => {
console.info("INPUT");
event.target.setCustomValidity('');
event.target.removeAttribute("pattern");
}
field.onchange = (event) => {
console.info("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>setCustomValidity предназначен для использования, когда несколько входов в комбинации недопустимы. Поэтому после этого необходимо вручную сбросить его на пустую строку. В противном случае следует использовать атрибут title.
Попытка скрыть ошибку проверки после редактирования ввода понятна, но противоречит философии формы HTML5. Он предназначен для отображения до тех пор, пока введенные данные недействительны.
Добавление максимальной длины может помочь пользователю не переступить верхний предел.
Если вы действительно хотите, чтобы ваши пункты списка были удовлетворены, не стесняйтесь использовать проверку формы 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.info("SUBMIT");
output.textContent = field.value;
e.preventDefault(); // Prevent default POST request
});
field.oninvalid = (event) => {
console.info("INVALID");
}
field.oninput = (event) => {
console.info("INPUT");
}
Какой браузер вы используете? Я протестировал вашу корзину в Chrome и Safari на Mac, и я не могу воспроизвести проблему в анимированном GIF. Отображается правильное сообщение и только тогда, когда ввод недействителен