Как установить обработчик события фокуса для динамически создаваемых элементов?

Добрый день! <br/> <br/> Ранее я использовал только jQuery, но сейчас решил перейти на чистый JavaScript. <br/> Я столкнулся с трудностью добавления события focus на динамически создаваемые элементы. <br/> <br/> Вот в чем заключается моя задача: <br/> у меня есть один textarea, и когда он получает фокус, ниже должен появиться такой же пустой textarea. При клике на следующий textarea — добавляется еще один и так далее. <br/> <br/> Я изучил информацию в Google и выяснил, что нельзя просто повесить событие на focus. В итоге я решил проблему следующим образом: <pre><code class="javascript">document.querySelector('.item-fields').addEventListener('click', function (e) {
     if (e.target.tagName === 'TEXTAREA') {
          let wrapFields = e.target.closest('.item-fields');
          let cloneField = e.target.closest('.item').cloneNode(true);
          cloneField.querySelector('.task-title').value = '';
          wrapFields.append(cloneField);
     }
});</code></pre> <br/> Однако теперь мне необходимо, чтобы при потере фокуса textarea отправлялся запрос на сервер для сохранения. Я не могу понять, как поймать событие focus, потому что сейчас, когда я кликаю после textarea, e.type = 'click'.
  • 13 сентября 2024 г. 11:53
Ответы на вопрос 3
Вам действительно правильно подходит подход, использующий делегирование событий. С его помощью вы можете обрабатывать события для динамически создаваемых элементов. В вашем случае для отслеживания события фокуса вы можете использовать `focusin` - это событие, которое срабатывает при фокусировке на элементе и его потомках.

Вот как вы можете изменить ваш код, чтобы добавить обработчик события `focus` для динамически создаваемых `textarea`, а также отправлять запрос на сервер при потере фокуса:

```javascript
// Получаем контейнер, в который будут добавляться textarea
const wrapFields = document.querySelector('.item-fields');

// Обработчик для кликов по textarea (для добавления нового)
wrapFields.addEventListener('click', function (e) {
    if (e.target.tagName === 'TEXTAREA') {
        // Клонируем текущий текстовый блок
        let cloneField = e.target.closest('.item').cloneNode(true);
        cloneField.querySelector('textarea').value = ''; // Очищаем текст
        wrapFields.append(cloneField);
    }
});

// Обработчик для фокуса и потери фокуса
wrapFields.addEventListener('focusin', function (e) {
    if (e.target.tagName === 'TEXTAREA') {
        // Здесь можно добавлять дополнительную логику при фокусе, если нужно
    }
});

wrapFields.addEventListener('focusout', function (e) {
    if (e.target.tagName === 'TEXTAREA') {
        const value = e.target.value;

        // Отправка данных на сервер
        sendToServer(value)
            .then(response => {
                console.log('Данные успешно отправлены', response);
            })
            .catch(error => {
                console.error('Ошибка при отправке данных', error);
            });
    }
});

// Пример функции для отправки данных на сервер
function sendToServer(data) {
    // Замените URL на нужный
    return fetch('https://example.com/api/submit', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({ value: data })
    });
}
```

### Объяснение кода:
1. **Делегирование событий**: Мы добавляем обработчики событий на контейнер `wrapFields`, что позволяет отслеживать события для `textarea`, даже если они создаются динамически.
  
2. **`focusin` и `focusout`**: Эти события позволяют вам отслеживать, когда элемент получает или теряет фокус. Внутри обработчика `focusout` мы добавляем логику для отправки данных на сервер.

3. **Функция отправки данных**: В этой функции используется `fetch` для отправки данных на сервер. Вы можете заменить URL `https://example.com/api/submit` на тот, который вам нужен.

Теперь, когда вы кликаете по `textarea` и затем выходите из него (теряете фокус), ваши данные будут отправлены на сервер.
К чёрту focus, используйте <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/focusin_event" rel="nofollow">focusin</a> , оно всплывает, в отличие от.
<pre><code class="javascript">document.querySelector('.item-fields').addEventListener('focusin', function (e) {
  // Элемент в фокусе
});
document.querySelector('.item-fields').addEventListener('focusout', function (e) {
  // Элемент потерял фокус
});</code></pre> <br/> <br/>
Похожие вопросы