Методы .delegate() и .undelegate()

Определение и применение

Метод .delegate() назначает обработчик родительскому элементу для событий подходящих потомков. Он работает и с потомками, добавленными позднее. Метод .undelegate() удаляет такие делегированные обработчики.

Синтаксис

JavaScript
root.delegate(selector, events, handler);
root.delegate(selector, events, eventData, handler);
root.delegate(selector, { click: handler });
root.undelegate(selector, events, handler);
root.undelegate(selector, events);
root.undelegate(selector, { click: handler });
root.undelegate(".panel");
root.undelegate();

Параметры и возвращаемое значение

selector задаёт потомков, events — типы событий и необязательные пространства имён. Событие должно дойти до корневого элемента. В обычной функции this указывает на совпавшего потомка, а event.delegateTarget — на родителя, где установлен обработчик.

Оба метода возвращают коллекцию корневых элементов. Вызов .undelegate() без аргументов снимает делегированные обработчики; одно строковое пространство имён ограничивает удаление соответствующей группой. Прямые обработчики — другой случай.

Особенности и совместимость

Оба метода устарели с 3.0, но доступны в 4.0. Замена требует поменять порядок аргументов: root.on(events, selector, handler) и root.off(events, selector, handler).

Если обработчик ниже по дереву остановил всплытие, делегирование может не сработать. В обработчике стрелочной функции нет собственного this; используйте аргумент события либо обычную функцию.

Документация

Пример старого кода

Динамический потомок: попробуйте сами

Кнопка создаётся после назначения делегирования. Первое событие обработается, после удаления обработчика — уже нет. Используется jQuery 4.0.0.

index.html
HTML
<div id="list"></div>
<pre id="result"></pre>
main.js
JavaScript
const root = $('#list')
let count = 0
function handle() {
    count++
}
root.delegate('button', 'click.demo', handle)
root.append('<button>Новый пункт</button>')
root.find('button').trigger('click')
root.undelegate('button', 'click.demo', handle)
root.find('button').trigger('click')
$('#result').text('Вызовов: ' + count)