Традиционные методы для решения этой задачи не подойдут, но в этом нет ничего сложного. Событие потеря фокуса с помощью JavaScript (js) на форме требует иного подхода и такого свойства как Event.relatedTarget и метода contains().
Создание формы
Допустим, у вас есть форма с несколькими элементами внутри, и вам требуется, например, запустить функцию в случае снятия с нее фокуса.
<form action="#!">
<label for="input1">Input 1</label>
<input type="text" id="input1" value="Hello">
<label for="input2">Input 2</label>
<input type="text" id="input2" value="world">
<label for="input3">Input 3</label>
<input type="text" id="input3" value="!">
<button>Submit</button>
</form>
Как же это сделать? Давайте попробуем разобраться.
Событие focusout
В нативном JavaScript есть такое событие, как focusout. И большинство новичков несомненно попробуют применить именно его.
const form = document.querySelector('form');
form.addEventListener('focusout', function (event) {
// Здесь можно написать код, который должен будет выполняться при снятии фокуса с формы
console.log('focus left!');
});
Но из-за принципа всплытия событий это не сработает при снятии фокуса с формы. Оно будет работать всякий раз, когда один из элементов внутри формы теряет фокус. Если требуется отследить переход, например, от одного инпута к другому, то потребуется указать callback в addEventListener. Можно также попытаться использовать event.target, но и это не будет работать. Все дело в том, что событие запускает input, который теряет фокус, а не тот, который его получает.
Читайте также: Очистка формы после отправки на чистом JavaScript.
Точно так же вы не сможете осуществить проверку и при помощи свойства document.activeElement. В этом случае событие срабатывает в каком-то странном промежуточном состоянии, когда текущий элемент потерял фокус, а новый его еще не получил.
form.addEventListener('focusout', function (event) {
// Здесь можно написать код, который должен будет выполняться при снятии фокуса с формы
console.log(event.target, document.activeElement);
});
Как же быть в этом случае?
Читайте также: Как проверить видимость элемента на js.
Он доступен только для событий focus и возвращает «вторичную цель». Она варьируется в зависимости от события. При применении focusin — это элемент, теряющий фокус, а при focusout — получающий его.
Event.relatedTarget и метод contains() позволяет отследить событие потеря фокуса при помощи JavaScript внутри формы.
// Здесь можно написать код, который должен будет выполняться при снятии фокуса с формы
form.addEventListener('focusout', function (event) {
// Если фокус все еще находится на форме, то ничего не происходит
if (form.contains(event.relatedTarget)) return;
// В противном случае в консоль выводится сообщение
console.log('Фокус снят!'); });
Событие потеря фокуса: кроссбраузерность
Event.relatedTarget воспринимается всеми современными браузерами, как и contains(), Но второй имеет лишь частичную поддержку в Internet Explorer и применим только к DOM-элементам.