Формы и события форм
События форм
submit— отправка формыreset— сбросinput— ввод в поле (мгновенно)change— изменение (после потери фокуса)focus,blur— фокусinvalid— ошибка валидации
Submit
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(form);
const data = Object.fromEntries(formData);
console.log(data);
});
preventDefault обязателен — иначе страница перезагрузится.
FormData
const formData = new FormData(form);
formData.get('email'); // значение
formData.getAll('tags'); // все значения
formData.has('email'); // true
formData.append('extra', '1');
formData.set('email', 'new@example.com');
formData.delete('extra');
Преобразование в объект:
const data = Object.fromEntries(formData);
Input vs change
input.addEventListener('input', () => {
console.log('на каждый символ');
});
input.addEventListener('change', () => {
console.log('после потери фокуса');
});
input — мгновенно, change — после завершения ввода.
Валидация
form.addEventListener('submit', (event) => {
if (!form.checkValidity()) {
event.preventDefault();
// показать ошибки
}
});
Встроенные атрибуты:
<input type="email" required>
<input type="text" minlength="3" maxlength="20">
<input type="number" min="0" max="100">
<input type="text" pattern="[A-Za-z]+">
Валидация через JS
input.addEventListener('input', () => {
if (input.validity.valid) {
input.classList.remove('invalid');
} else {
input.classList.add('invalid');
}
});
Свойства validity:
valueMissing— не заполненоtypeMismatch— неверный типpatternMismatch— не соответствует patterntooShort,tooLongrangeUnderflow,rangeOverflowvalid— всё ок
Кастомные сообщения
input.addEventListener('invalid', (event) => {
event.target.setCustomValidity('Введите корректный email');
});
input.addEventListener('input', (event) => {
event.target.setCustomValidity('');
});
Checkbox
checkbox.addEventListener('change', () => {
console.log(checkbox.checked); // true/false
});
Radio
document.querySelectorAll('input[name="gender"]').forEach((radio) => {
radio.addEventListener('change', () => {
if (radio.checked) console.log(radio.value);
});
});
Или через форму:
form.addEventListener('change', (event) => {
if (event.target.name === 'gender') {
console.log(event.target.value);
}
});
Select
select.addEventListener('change', () => {
console.log(select.value);
console.log(select.selectedOptions); // выбранные option
});
Множественный:
[...select.selectedOptions].map((o) => o.value);
Файлы
fileInput.addEventListener('change', () => {
const files = fileInput.files;
for (const file of files) {
console.log(file.name, file.size, file.type);
}
});
Отправка через fetch
form.addEventListener('submit', async (event) => {
event.preventDefault();
const formData = new FormData(form);
try {
const res = await fetch('/api/submit', {
method: 'POST',
body: formData,
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
form.reset();
showSuccess();
} catch (error) {
showError(error.message);
}
});
Не устанавливай Content-Type для FormData — браузер сам.
JSON
const data = Object.fromEntries(new FormData(form));
await fetch('/api/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
Сброс
form.reset(); // к значениям по умолчанию
Итоги
submit+preventDefaultFormDataдля сбораinputмгновенно,changeпосле- Валидация через
checkValidityили атрибуты validityдля детальной проверки- Отправка через
fetchсFormDataили JSON