Focus на элементе form: будет ли работать?
Короткий ответ: Нет, focus на <form> элементе НЕ работает так как ожидается. Это важная нюанс HTML/DOM.
Почему focus не работает на форме
<form> — это контейнерный элемент, а не интерактивный элемент. Focus в браузере может устанавливаться только на фокусируемые элементы (focusable elements):
Фокусируемые элементы:
<a>, <button>, <input>, <select>, <textarea>
<area>, <details>, <iframe>
- Элементы с
contenteditable="true"
- Элементы с
tabindex >= 0
- И несколько других
НЕ фокусируемые по умолчанию:
<form>
<div>, <span>, <p> и другие контейнеры
<img>, <video> и медиа элементы
<ul>, <ol>, <li> и списки
Практический пример
<form id="myForm">
<input type="text" placeholder="Name">
<input type="email" placeholder="Email">
<button type="submit">Submit</button>
</form>
<script>
const form = document.getElementById('myForm');
form.focus();
console.log(document.activeElement);
console.log(form === document.activeElement);
</script>
Как сделать форму фокусируемой
Вариант 1: Добавить tabindex
<form id="myForm" tabindex="-1">
<input type="text" placeholder="Name">
<input type="email" placeholder="Email">
<button type="submit">Submit</button>
</form>
<script>
const form = document.getElementById('myForm');
form.focus();
console.log(document.activeElement);
</script>
Значения tabindex:
tabindex="-1" — элемент фокусируется программно, но НЕ через Tab
tabindex="0" — элемент получает фокус в порядке Tab
tabindex="1" и выше — приоритет для Tab (НЕ рекомендуется)
Вариант 2: Фокусировать первый input
Это чаще всего то, что нужно на практике:
<form id="myForm">
<input id="firstName" type="text" placeholder="Name">
<input type="email" placeholder="Email">
<button type="submit">Submit</button>
</form>
<script>
const form = document.getElementById('myForm');
const firstInput = document.getElementById('firstName');
firstInput.focus();
</script>
Реальные примеры использования
1. Открыть модалку и фокусировать форму
function openModal() {
const modal = document.getElementById('modalForm');
const firstInput = modal.querySelector('input, select, textarea');
if (firstInput) {
firstInput.focus();
}
modal.setAttribute('tabindex', '-1');
modal.focus();
}
2. React компонент
import React, { useRef } from 'react';
function MyForm() {
const formRef = useRef<HTMLFormElement>(null);
const firstInputRef = useRef<HTMLInputElement>(null);
const handleOpenForm = () => {
firstInputRef.current?.focus();
formRef.current?.setAttribute('tabindex', '-1');
formRef.current?.focus();
};
return (
<>
<button onClick={handleOpenForm}>Open Form</button>
<form ref={formRef}>
<input ref={firstInputRef} type="text" placeholder="Name" />
<input type="email" placeholder="Email" />
<button type="submit">Submit</button>
</form>
</>
);
}
3. Контроль фокуса в форме
function FormWithFocusControl() {
const formRef = useRef<HTMLFormElement>(null);
const [focusedField, setFocusedField] = React.useState<string | null>(null);
const focusField = (fieldName: string) => {
const input = formRef.current?.querySelector(
`input[name="${fieldName}"]`
) as HTMLInputElement;
if (input) {
input.focus();
setFocusedField(fieldName);
}
};
return (
<form ref={formRef}>
<input
name="firstName"
type="text"
placeholder="Name"
onFocus={() => setFocusedField('firstName')}
/>
<input
name="email"
type="email"
placeholder="Email"
onFocus={() => setFocusedField('email')}
/>
{/* Кнопка для фокусировки firstName -->
<button type="button" onClick={() => focusField('firstName')}>
Focus Name
</button>
<div>{focusedField && `Focused: ${focusedField}`}</div>
</form>
);
}
Проверка фокусируемости элемента
function isFocusable(element: HTMLElement): boolean {
const focusableSelectors = [
'a[href]',
'button',
'input',
'select',
'textarea',
'[tabindex]'
];
return focusableSelectors.some(
selector => element.matches(selector)
);
}
const form = document.querySelector('form');
console.log(isFocusable(form));
const input = form?.querySelector('input');
console.log(isFocusable(input));
Лучшие практики
-
Не фокусируй форму — фокусируй первый input:
const firstInput = form.querySelector('input, select, textarea');
firstInput?.focus();
-
Управляй фокусом для доступности:
submitButton.focus();
-
Используй tabindex=-1 осторожно:
<div role="dialog" tabindex="-1">...</div>
-
Тестируй фокус:
const canFocus = () => {
const prevActive = document.activeElement;
element.focus();
const isFocused = document.activeElement === element;
prevActive?.focus?.();
return isFocused;
};
Заключение
Вопрос: Будет ли работать focus на форме?
Ответ: Нет, <form> по умолчанию не фокусируется. Нужно:
- Либо добавить
tabindex="-1" на форму
- Либо (чаще всего) фокусировать первый input внутри формы
Это частая ошибка в разработке, поэтому важно понимать какие элементы фокусируются, а какие нет.