4. 4
PubSub
• Издатель (Publisher)
– Генерирует данные одного типа
– Издает только одну газету
– Издателей может быть много
• Подписчики (Subscribers)
– Подписываются на данные издателя
– Могут отписаться в любой момент
• Данные – поток
– Поздно подписался – упустил данные
– Объем и частота публикаций задается издателем
5. 5
var PubSub = function () {
this.readers = [];
};
PubSub.prototype = {
pub: function (data) {},
sub: function (callback) {},
unsub: function (callback) {}
};
// function callback(data) {}
PubSub – пример
6. 6
PubSub – особенности
• Самая простая реализация
• Только 1 тип данных
– А хочется еще и "Мурзилку" получать
• Нужно напрямую общаться с объектом
8. 8
Event Emitter
• Имеет много названий
• Издатель
– Генерирует данные разных типов
– Издает газеты и журналы
– Издателей может быть много
• Подписчики
– Подписываются на данные любого типа в любом количестве
– Могут отписаться в любой момент
• Данные – поток
– Поздно подписался – упустил данные
– Объем и частота публикаций задается издателем
9. 9
var EventEmitter = function () {
// events = {"event_name": []};
this.events = {};
};
EventEmitter.prototype = {
emit: function (event, data) {},
on: function (event, callback) {},
off: function (event, callback) {}
};
// function callback(data) {}
Event Emitter – пример
10. 10
Event Emitter – особенности
• Много разных типов данных
• Нужно иметь ссылку на EventEmitter
12. 12
Event Manager
• Имеет много названий
• Своеобразная шина данных
• Единственный издатель
– Генерирует данные разных типов
• Подписчики
– Подписываются на данные любого типа в любом количестве
– Могут отписаться в любой момент
• Данные – поток
– Поздно подписался – упустил данные
– Объем и частота публикаций задается издателем
13. 13
Похож на Event Emitter, но это Синглентон
var EventManager = {
events: {},
emit: function (event, data) {},
on: function (event, callback) {},
off: function (event, callback) {}
};
// function callback(data) {}
Event Manager – пример
14. 14
Event Manager – особенности
• Много разных типов данных
• Об этом объекте знают все
19. 19
jQuery 1.8
var handler = function () {};
$('body').on('click.ns', handler);
$('body').off('click', handler); // не удобно
$('body').off('click'); // все click
$('body').off('.ns'); // весь namespace
$('body').off(); // все события
$('body').off('**'); // все делегированные
Управление событиями – пример
20. 20
Накопление данных
• Опоздал с подпиской – ничего не получил
– Это не удобно
• Пользователь желает получить все
– Всю подписку журналов с нуля
• Как только подписался – сразу получил
• Похоже на Promise
29. 29
Event bubbling – фаза по умолчанию в jQuery
// jQuery 1.7 .on()
$('.b-form-button').on('click', function (event) {
console.log(this); // .b-form-button element
});
// Хэлперы
$('.b-form-button').click(function (event) {
console.log(event);
});
Event bubbling в jQuery
http://api.jquery.com/on/
http://api.jquery.com/category/events/
http://api.jquery.com/category/events/event-object/
30. 30
Функция bindTo()
BEM.DOM.decl('b-form-input', {
onSetMod : {
'js' : {
'inited' : function () {
this
.bindTo(this.elem('input'), {
'focus' : this.onFocus,
'blur' : this.onBlur
});
}
}
}
});
Event bubbling в i-bem
http://bem.github.com/bem-bl/sets/common-
desktop/i-bem/i-bem.ru.html
31. 31
Не всплывающие события
• var itBubbles = event.bubbles;!
• Специфичные события для 1 элемента
– submit, focus, blur, load, unload, change, reset, scroll
• Некоторые события мутаций DOM
– DOMFocusIn, DOMFocusOut, DOMNodeRemoved
https://developer.mozilla.org/en-US/docs/
Mozilla_event_reference
32. 32
Особенности
• Фазы Capturing & Bubbling идут
одновременно
– Чередуются capturing, bubbling
• Каждый обработчик получает новый инстанс
объекта Event
http://jsfiddle.net/h2nJU/2/
42. 42
Профит делегирования
• Меньше обработчиков событий
– Экономия памяти
– Меньше утечек памяти
• Проще работать с динамическими
элементами
43. 43
Особенности делегирования
• Если событие не всплывает – ничего не
получится
• Нужно максимально ограничивать событие
– Необходимо выбрать наиболее близкого делегата
• Возможны частые ложные вызовы события
– Большие затраты на вызов функции
• Ограничить делегирование у частых
событий
– mousemove
• Не использовать делегирование если
элемент 1
48. 48
Прерывание действия по умолчанию
• Действие по умолчанию
– Переход по ссылке
– Раскрытие <select>
– Сабмит формы
– Фокус в инпут
– Снятие фокуса
• event.preventDefault()
– Перерывает это действие
• Некоторые действия прервать нельзя
– var isCanPrevent = event.cancelable;
– resize, scroll, focus, error, load, unload, DOM*, …
https://developer.mozilla.org/en-US/docs/DOM/
event.preventDefault
49. 49
$('.b-link').click('click', function (event) {
return false; // preventDefault+stopPropagation
});
$('.b-form').click('submit', function (event) {
return isValid(this); // this - .b-form
});
$('.b-link').click('click', function (event) {
event.preventDefault();
event.stopPropagation();
});
Прерывание событий jQuery
http://api.jquery.com/on/
http://api.jquery.com/live/
62. 62
Вариант не удачного использования событий
DataObject.on('someData', function (data) {
console.log(data);
});
DataObject.trigger('giveMe:someData');
Событие геттер
71. 71
Накладные расходы
• Событие – функция
– n объектов, k ресурсов = n*k функций
– функция занимает ресурсы
– лишние скоупы, сборка мусора и JIT-компиляция
– вызов кучи функций
– утечки памяти
73. 73
Не блокирующий I/O
• Дефрагментация времени блокировок
– Более плотная загрузка процесса
• Выгодно применять, когда время I/O больше
времени обработки данных
• Меньше проблем с разделяемой памятью
74. 74
Слабое связывание
• Элементы не знают о программе
• Элементы общаются только событиями
• Меньше разделенной памяти
– Меньше проблем синхронизации
76. 76
Заключение
• События
– PubSub
– Event Emitter
– Event Manager
• Фичи событий
– namespace
– накопление данных
• DOM события
– Event Bubbling
– Делегирование
– Прерывание события
– Отмена действия по умолчанию
• Фильтрация