Делегирование событий — один из ключевых инструментов оптимизации работы с DOM в Riot.js. Этот механизм позволяет назначать обработчики событий на родительский элемент и управлять событиями всех вложенных элементов без необходимости вешать отдельный обработчик на каждый элемент. Такой подход повышает производительность приложения и упрощает управление динамически создаваемыми элементами.
В основе делегирования событий лежит всплытие
событий в DOM. Когда событие происходит на элементе, оно
поднимается по дереву DOM до корневого элемента, позволяя обработчику,
назначенному на родителя, определить источник события через объект
event.target.
В Riot.js делегирование встроено в синтаксис компонентов. Для этого
используется директива on-* с указанием события.
Например:
<my-list>
<ul>
<li each={item in items} oncl ick={handleClick}>{item}</li>
</ul>
<script>
export default {
items: ['Элемент 1', 'Элемент 2', 'Элемент 3'],
handleClick(event) {
console.log('Клик по элементу:', event.target.innerText);
}
}
</script>
</my-list>
В этом примере обработчик handleClick назначен на каждый
<li>. Однако при большом количестве элементов это
может негативно сказаться на производительности. Делегирование позволяет
назначить обработчик на <ul>, используя проверку
event.target для определения целевого элемента.
Делегирование в Riot.js реализуется через назначение обработчиков на контейнеры и фильтрацию по селекторам. Пример:
<my-list>
<ul oncl ick={delegateClick}>
<li each={item in items} data-index={index}>{item}</li>
</ul>
<script>
export default {
items: ['Элемент 1', 'Элемент 2', 'Элемент 3'],
delegateClick(event) {
const li = event.target.closest('li');
if (!li) return;
const index = li.dataset.index;
console.log('Клик на элемент с индексом:', index);
}
}
</script>
</my-list>
Здесь событие клика отслеживается на <ul>. Метод
closest('li') позволяет определить, на каком элементе
произошло событие. Это позволяет эффективно управлять любым количеством
элементов без назначения отдельного обработчика для каждого
<li>.
Для передачи дополнительных данных через делегирование можно использовать атрибуты или dataset. Например:
<my-list>
<ul oncl ick={delegateClick}>
<li each={item, index in items} data-id={item.id}>{item.name}</li>
</ul>
<script>
export default {
items: [
{id: 101, name: 'Элемент A'},
{id: 102, name: 'Элемент B'}
],
delegateClick(event) {
const li = event.target.closest('li');
if (!li) return;
const itemId = li.dataset.id;
console.log('Выбран элемент с ID:', itemId);
}
}
</script>
</my-list>
Использование data-* атрибутов позволяет передавать
уникальные идентификаторы элементов, избегая прямой зависимости от
индексов или содержимого.
Riot.js поддерживает кастомные события, которые можно делегировать аналогично стандартным DOM-событиям. Например:
<child-component on:custom-event={handleCustomEvent}></child-component>
<script>
export default {
handleCustomEvent(event) {
console.log('Кастомное событие:', event.detail);
}
}
</script>
Для делегирования кастомных событий используется та же логика: событие поднимается от компонента-наследника к родителю, позволяя родительскому компоненту обрабатывать события без необходимости прямой привязки к каждому дочернему элементу.
dataset и обрабатывать кастомные события компонентов.event.target.closest() для проверки
источника события, чтобы избежать нежелательных срабатываний.Делегирование событий в Riot.js является мощным инструментом для построения масштабируемых, быстрых и поддерживаемых пользовательских интерфейсов.