Переход от классического управления событиями к делегированию событий в JavaScript ООП
Старое управление событиями, в котором каждый обработчик для определенных действий был напрямую подключен к целевому элементу, устарело, поскольку соображения по поводу производительности и экономии памяти стали распространяться в сообществе разработчиков.
Реализации делегирования событий получили ускорение, так как jQuery обновил старомодный.bind()
а также.live()
методы с новым.on()
способ разрешить делегирование.
Это определяет изменение в некоторых закаленных подходах, где для использования делегирования события необходима доработка. Я пытаюсь выработать некоторые лучшие практики, сохраняя при этом стиль кодирования моей библиотеки, и искал похожие ситуации, с которыми сталкивались другие разработчики, чтобы найти ответ.
Используя ООП с функциями в качестве конструкторов, у меня обычно есть интерфейсы для создания объектов:
var widget = new Widget({
timeout: 800,
expander: '.expanders'
});
с объектными литералами, заданными в качестве аргумента, обеспечивая чистую карту имен и значений переданного ввода. Класс, лежащий в основе этого кода, может выглядеть примерно так:
var Widget = function(options) {
// some private members
var _timeout;
var _$widget;
var _$expander;
// methods
this.init = function() {
_timeout = options.timeout || 500;
_$expander = $(options.expander);
_$widget = _$expander.next();
_$expander.on('click', _toggle);
};
var _toggle = function(e) {
if (_$widget.is(':visible')) {
_$widget.hide(_timeout);
} else {
_$widget.show(_timeout);
}
};
this.init();
};
С помощью "частный" методы дали мне некоторые преимущества с точки зрения читабельности и чистоты кода (только полезные методы открыты для пользователя), помимо небольшого выигрыша в производительности (каждое разрешение области занимает больше времени, чем локальная переменная). Но если говорить о обработчиках событий, это противоречит парадигме делегирования событий.
Я думал обнародовать методы, которые я использовал для внутреннего сопоставления со слушателями в классе:
this.toggle = function(e) {
if (_$widget.is(':visible')) {
_$widget.hide(_timeout);
} else {
_$widget.show(_timeout);
}
};
затем вождение извне или в другом прокси-классе, правильное делегирование с чем-то вроде этого:
var widget = new Widget({
expander: '.expanders'
});
$(delegationContext).on('click', '.expanders', widget.toggle);
но это не показалось мне лучшим подходом - не показывать бесполезный метод в интерфейсе, поэтому я попытался дать основному классу возможность напрямую узнать всю информацию, чтобы делегировать событие автономно через интерфейс:
var widget = new Widget({
timeout: 800,
expander: {
delegationContext: '.widgetContainer',
selector: '.expanders'
}
});
что позволило бы продолжать использовать закрытые методы внутри класса:
var $context = $(options.expander.delegationContext);
$context.on('click', options.expander.selector, _toggle);
Каковы ваши практики и предложения по этому поводу?
Каковы основные тренды других разработчиков, о которых вы слышали сегодня?