Это действительно интересный вопрос. Тем не менее, мне любопытно о чем-то. Chrome будет сохранять только autocomplete
значения при отправке формы (как указано здесь ). Логично, что если у ввода есть minlength
из 5 и вы вводите что-то длиной 4, вы не сможете отправить форму в первую очередь . Следовательно, недопустимое значение автозаполнения не должно быть сохранено. Как вы впервые столкнулись с такой ситуацией? Я смог воспроизвести его только с помощью , а не , установив minlength
, отправив, затем установив minlength
и попробовав автозаполнение.
Чтобы ответить на ваш вопрос, это поведение не является ошибкой. minlength
не работает, потому что он не предназначен для проверки значений, вставленных autofill
. Подробнее читайте ниже.
Почему minlength
не работает?
Почему minlength
не делает недействительными значения, заданные autocomplete
, когда длина значений меньше указанной minlength
? Упомянутый в стандарте HTML от WHATWG , minlength
имеет проверку этого ограничения:
Если элемент имеет минимально допустимую длину значения, его флаг «грязное» значение имеет значение true, его значение в последний раз изменялось пользователем (в отличие от изменения, выполненного сценарием), его значение не является пустой строкой, а длина строки JavaScript значения API элемента меньше минимально допустимой длины значения элемента , тогда элемент страдает от слишком короткого.
Становится очевидным, что значение будет проверено minlength
только тогда, когда его значение было изменено редактированием пользователя , а не по сценарию. Читая далее, мы можем сделать вывод, что значения autofill
вставляются скриптом (читайте здесь ). Мы можем проверить minlength
не проверяя значения ввода, когда они изменяются скриптом, выполнив следующее (пожалуйста, вставьте слово «Проверка» во вход):
const input = document.querySelector('input')
input.addEventListener('keyup', e => {
if (input.value === "Testing") input.value = "Test"
})
input:invalid {
outline: 1px solid red;
}
<input type="text" minlength="5">
Вы можете видеть, что он не потрудился проверить input
, когда его значение было изменено сценарием на "Test".
Использование pattern
pattern
, с другой стороны, не имеет проверки ограничения, говоря, что значения должны быть изменены путем редактирования пользователем. Вы можете прочитать о проверке ограничения здесь . Поэтому вы все равно можете изменить значение input
с помощью скрипта, и оно все равно будет работать. Попробуйте еще раз ввести «Тестирование» в input
:
const input = document.querySelector('input')
input.addEventListener('keyup', e => {
if (input.value === "Testing") input.value = "Test"
})
input:invalid {
outline: 1px solid red;
}
<input type="text" pattern="[0-9a-zA-Z]{5,}">
Когда оно меняется на «Тест», оно становится недействительным на pattern
и вызывает срабатывание CSS. Это означает, что вы можете использовать pattern
для проверки значений, заданных autofill
. (Еще любопытно, как это ошибочное значение autofill
сохраняется в первую очередь.)
Вот решение, использующее pattern
для проверки input
, заданного autofill
с некоторыми корректировками:
* {
box-sizing: border-box;
margin: 0;
font-family: Helvetica;
}
body {
padding: 20px;
}
#checkout_form * {
display: block;
margin: 1em;
}
#first_name {
padding: 10px;
border-radius: 5px;
width: 400px;
border: 1px solid #00000044;
outline: none;
}
#first_name::placeholder {
color: #00000040;
}
#submit_form {
padding: 10px;
border-radius: 5px;
border: none;
background: #7F00FF;
color: #ffffffee;
width: 200px;
}
#checkout_form input:invalid {
padding-right: calc(1.5em + .75rem);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: center right calc(.375em + .1875rem);
background-size: calc(.75em + .375rem) calc(.75em + .375rem);
border: 1px solid #CC0000ee;
}
#checkout_form input:valid {
padding-right: calc(1.5em + 0.75rem);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23ffcc00' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right calc(0.375em + 0.1875rem) center;
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
border: 1px solid #00cc00ee;
}
@-webkit-keyframes autofillvalid {
0%,
100% {
color: #ffcc00;
background: none;
padding-right: calc(1.5em + 0.75rem);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23ffcc00' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right calc(0.375em + 0.1875rem) center;
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}
}
@-webkit-keyframes autofillinvalid {
0%,
100% {
background: none;
padding-right: calc(1.5em + .75rem);
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: center right calc(.375em + .1875rem);
background-size: calc(.75em + .375rem) calc(.75em + .375rem);
}
}
input:-webkit-autofill:valid {
-webkit-animation-name: autofillvalid;
-webkit-animation-fill-mode: both;
}
input:-webkit-autofill:invalid {
-webkit-animation-name: autofillinvalid;
-webkit-animation-fill-mode: both;
}
<form id="checkout_form">
<input type="text" required id="first_name" name="fname" placeholder="Enter your first name" pattern="[0-9a-zA-Z]{5,}" autocomplete="given-name" title="First Name should be at least 5 characters and must consist only of alphabets and/or numbers">
<button id="submit_form" type="submit">Submit</button>
</form>
Более того, я весьма рекомендую прочитать больше о autofill
и о том, как его лучше использовать здесь .