← Назад к вопросам

Какие события отлавливают фокус?

2.0 Middle🔥 201 комментариев
#Soft Skills и рабочие процессы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Управление фокусом в DOM: события и их применение

В веб-разработке управление фокусом — критически важный аспект доступности (a11y) и пользовательского опыта. Браузер предоставляет несколько событий фокуса, которые позволяют отслеживать и реагировать на изменения в активном элементе страницы. Рассмотрим основные события и их особенности.

Основные события фокуса

1. focus и focusin

Событие focus возникает, когда элемент получает фокус (например, при клике мышью, переходе по Tab, или программном вызове .focus()). Важное отличие: focus не всплывает (non-bubbling).

// Пример с focus (не всплывает)
const input = document.querySelector('input');
input.addEventListener('focus', (event) => {
    console.log('Элемент получил фокус', event.target);
});

// focusin — всплывающий аналог
document.addEventListener('focusin', (event) => {
    console.log('Фокус внутри документа на:', event.target);
});

Событие focusin является всплывающим аналогом focus и позволяет отлавливать фокус на уровне родительских элементов.

2. blur и focusout

Противоположные события возникают при потере фокусa:

  • blur — не всплывает
  • focusout — всплывает
// Отслеживание потери фокуса
input.addEventListener('blur', () => {
    console.log('Проверка ввода при потере фокуса');
    validateInput(input.value);
});

// Всплывающая версия
form.addEventListener('focusout', (event) => {
    if (event.target.tagName === 'INPUT') {
        console.log('Поле вышло из фокуса');
    }
});

Практическое применение событий фокуса

Валидация форм

События фокуса идеально подходят для инлайн-валидации полей ввода:

const emailInput = document.getElementById('email');
emailInput.addEventListener('blur', () => {
    const isValid = validateEmail(emailInput.value);
    if (!isValid) {
        showError('Введите корректный email');
        emailInput.focus(); // Возвращаем фокус на поле с ошибкой
    }
});

Улучшение доступности

Для пользователей скринридеров важно правильно управлять фокусом при динамических изменениях:

// Перемещение фокуса при открытии модального окна
function openModal() {
    modal.style.display = 'block';
    modal.focus(); // Передаем фокус модальному окну
    modal.setAttribute('tabindex', '-1'); // Делаем фокусируемым
}

// Возврат фокуса при закрытии
function closeModal() {
    modal.style.display = 'none';
    lastFocusedElement.focus(); // Возвращаем фокус на предыдущий элемент
}

Управление фокусом в SPA

В одностраничных приложениях важно правильно восстанавливать фокус при навигации:

// Запоминаем текущий элемент с фокусом
let previousFocus = null;

router.beforeEach((to, from, next) => {
    previousFocus = document.activeElement;
    next();
});

router.afterEach(() => {
    // После смены маршрута проверяем, нужен ли фокус на новом элементе
    const mainHeading = document.querySelector('h1');
    if (mainHeading) {
        mainHeading.setAttribute('tabindex', '-1');
        mainHeading.focus();
    }
});

Советы по работе с фокусом

  • Используйте делегирование событий через focusin/focusout для эффективной обработки
  • Избегайте блокировки фокуса без веской причины — это нарушает доступность
  • Тестируйте с клавиатуры — убедитесь, что все интерактивные элементы доступны через Tab
  • Учитывайте порядок табуляции при динамическом добавлении элементов
  • Используйте tabindex осмотрительно:
    • tabindex="0" — элемент в естественном порядке табуляции
    • tabindex="-1" — элемент фокусируем программно, но не через Tab
    • tabindex > 0избегайте, это нарушает естественный порядок

Расширенные сценарии

Кастомные элементы управления

Для создания кастомных элементов (например, виджета с вкладками) необходимо тщательно управлять фокусом:

class TabWidget {
    constructor(container) {
        this.tabs = container.querySelectorAll('.tab');
        this.panels = container.querySelectorAll('.panel');
        this.setupFocusManagement();
    }
    
    setupFocusManagement() {
        this.tabs.forEach((tab, index) => {
            tab.addEventListener('keydown', (event) => {
                if (event.key === 'ArrowRight') {
                    // Перемещение фокуса на следующую вкладку
                    this.tabs[(index + 1) % this.tabs.length].focus();
                }
            });
        });
    }
}

Отслеживание траектории фокуса

Иногда необходимо знать весь путь перемещения фокуса:

const focusPath = [];

document.addEventListener('focusin', (event) => {
    focusPath.push({
        element: event.target.tagName,
        id: event.target.id,
        timestamp: Date.now()
    });
    
    // Ограничиваем историю
    if (focusPath.length > 10) {
        focusPath.shift();
    }
});

Правильная работа с событиями фокуса — ключевой навык для создания доступных и удобных веб-интерфейсов. Она требует внимания к деталям, но значительно улучшает пользовательский опыт для всех, особенно для людей с ограниченными возможностями.

Какие события отлавливают фокус? | PrepBro