javascript. event model (in russian)

77

Upload: mikhail-davydov

Post on 28-Nov-2014

316 views

Category:

Technology


5 download

DESCRIPTION

 

TRANSCRIPT

Page 1: JavaScript. Event Model (in russian)
Page 2: JavaScript. Event Model (in russian)

Михаил Давыдов Разработчик JavaScript

JavaScript События

Page 3: JavaScript. Event Model (in russian)

Паттерн PubSub

Page 4: JavaScript. Event Model (in russian)

4

PubSub

• Издатель (Publisher) –  Генерирует данные одного типа –  Издает только одну газету –  Издателей может быть много

• Подписчики (Subscribers) –  Подписываются на данные издателя –  Могут отписаться в любой момент

• Данные – поток –  Поздно подписался – упустил данные –  Объем и частота публикаций задается издателем

Page 5: JavaScript. Event Model (in russian)

5

var PubSub = function () { this.readers = []; }; PubSub.prototype = { pub: function (data) {}, sub: function (callback) {}, unsub: function (callback) {} }; // function callback(data) {}

PubSub – пример

Page 6: JavaScript. Event Model (in russian)

6

PubSub – особенности

• Самая простая реализация • Только 1 тип данных

–  А хочется еще и "Мурзилку" получать

• Нужно напрямую общаться с объектом

Page 7: JavaScript. Event Model (in russian)

Event Emitter

Page 8: JavaScript. Event Model (in russian)

8

Event Emitter

• Имеет много названий • Издатель

–  Генерирует данные разных типов –  Издает газеты и журналы –  Издателей может быть много

• Подписчики –  Подписываются на данные любого типа в любом количестве –  Могут отписаться в любой момент

• Данные – поток –  Поздно подписался – упустил данные –  Объем и частота публикаций задается издателем

Page 9: JavaScript. Event Model (in russian)

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 – пример

Page 10: JavaScript. Event Model (in russian)

10

Event Emitter – особенности

• Много разных типов данных • Нужно иметь ссылку на EventEmitter

Page 11: JavaScript. Event Model (in russian)

11

Event Manager

Page 12: JavaScript. Event Model (in russian)

12

Event Manager

• Имеет много названий • Своеобразная шина данных • Единственный издатель

–  Генерирует данные разных типов

• Подписчики –  Подписываются на данные любого типа в любом количестве –  Могут отписаться в любой момент

• Данные – поток –  Поздно подписался – упустил данные –  Объем и частота публикаций задается издателем

Page 13: JavaScript. Event Model (in russian)

13

Похож на Event Emitter, но это Синглентон

var EventManager = { events: {}, emit: function (event, data) {}, on: function (event, callback) {}, off: function (event, callback) {} }; // function callback(data) {}

Event Manager – пример

Page 14: JavaScript. Event Model (in russian)

14

Event Manager – особенности

• Много разных типов данных • Об этом объекте знают все

Page 15: JavaScript. Event Model (in russian)

Дополнительные фичи

Управление событиями, namespace

Накопление данных

События на дереве DOM

Делегирование событий

Фильтрация событий

Page 16: JavaScript. Event Model (in russian)

Их наличие зависит от конкретны задач

Page 17: JavaScript. Event Model (in russian)

Фичи направлены на управление группами событий и агрегацией

Page 18: JavaScript. Event Model (in russian)

18

Управление событиями

• Группировка событий –  namespace

• Легкое удаление событий –  Удаление события без callback –  Удаление по дескриптору

Page 19: JavaScript. Event Model (in russian)

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('**'); // все делегированные

Управление событиями – пример

Page 20: JavaScript. Event Model (in russian)

20

Накопление данных

• Опоздал с подпиской – ничего не получил –  Это не удобно

• Пользователь желает получить все –  Всю подписку журналов с нуля

• Как только подписался – сразу получил • Похоже на Promise

Page 21: JavaScript. Event Model (in russian)

21

jQuery DOMReady

$(function () { $(function () { console.log('Tada!'); }); });

Накопление данных – пример

Page 22: JavaScript. Event Model (in russian)

22

jQuery Ajax#done

var data = $.get('/'); data.done(function () { data.done(function () { console.log('Tada!'); }); });

Накопление данных – пример

Page 23: JavaScript. Event Model (in russian)

DOM события

События на DOM дереве

Event bubbling

Event capturing

Не всплывающие события

Page 24: JavaScript. Event Model (in russian)

24

Event bubbling

• Событие начинается с текущего элемента • Поднимается по DOM дереву • Последний элемент – корень дерева

–  window или document

Page 25: JavaScript. Event Model (in russian)

25

<div>

Event bubbling

<div> <div>

*Click*

Page 26: JavaScript. Event Model (in russian)

26

<div>

Event bubbling

<div> <div>

*Click*

Page 27: JavaScript. Event Model (in russian)

27

<div>

Event bubbling

<div> <div>

*Click*

Page 28: JavaScript. Event Model (in russian)

28

<div>

Event bubbling

<div> <div>

*Click*

Page 29: JavaScript. Event Model (in russian)

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/

Page 30: JavaScript. Event Model (in russian)

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

Page 31: JavaScript. Event Model (in russian)

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

Page 32: JavaScript. Event Model (in russian)

32

Особенности

• Фазы Capturing & Bubbling идут одновременно –  Чередуются capturing, bubbling

• Каждый обработчик получает новый инстанс объекта Event

http://jsfiddle.net/h2nJU/2/

Page 33: JavaScript. Event Model (in russian)

Делегирование

Один обработчик – несколько целей

Основа – всплытие событий

Page 34: JavaScript. Event Model (in russian)

34

<ul> onclick=delegateClick

Делегирование

<li class="good"> *Click* <li class="good">

<li class="bad">

Page 35: JavaScript. Event Model (in russian)

35

<ul> onclick=delegateClick

Делегирование – начало события

<li class="good"> *Click* <li class="good">

<li class="bad">

Page 36: JavaScript. Event Model (in russian)

36

<ul> onclick=delegateClick

Делегирование – всплытие события

<li class="good"> *Click* <li class="good">

<li class="bad">

Page 37: JavaScript. Event Model (in russian)

37

var isTarget = event.target.classList .contains('good');

Page 38: JavaScript. Event Model (in russian)

38

<ul> onclick=delegateClick

Делегирование

<li class="good">

<li class="good">

<li class="bad"> *Click*

Page 39: JavaScript. Event Model (in russian)

39

<ul> onclick=delegateClick

Делегирование – начало события

<li class="good">

<li class="good">

<li class="bad"> *Click*

Page 40: JavaScript. Event Model (in russian)

40

<ul> onclick=delegateClick

Делегирование – всплытие события

<li class="good">

<li class="good">

<li class="bad"> *Click*

Page 41: JavaScript. Event Model (in russian)

41

Событие не произойдет

contains('good') === false;

Page 42: JavaScript. Event Model (in russian)

42

Профит делегирования

• Меньше обработчиков событий –  Экономия памяти –  Меньше утечек памяти

• Проще работать с динамическими элементами

Page 43: JavaScript. Event Model (in russian)

43

Особенности делегирования

• Если событие не всплывает – ничего не получится

• Нужно максимально ограничивать событие –  Необходимо выбрать наиболее близкого делегата

• Возможны частые ложные вызовы события –  Большие затраты на вызов функции

• Ограничить делегирование у частых событий –  mousemove

• Не использовать делегирование если элемент 1

Page 44: JavaScript. Event Model (in russian)

44

// jQuery 1.7+ .on() $('.b-container') .on('click', '.b-item', function (event) { console.log(this); // .b-item }); // jQuery 1.3+ $('.b-item') .live('click', function (event) { console.log(this); // .b-item }); // === $(document).on('click', '.b-item')

Делегирование в jQuery

http://api.jquery.com/on/ http://api.jquery.com/live/

Page 45: JavaScript. Event Model (in russian)

Управление DOM событием

Прерывание всплытия

Прерывание действия по умолчанию

Page 46: JavaScript. Event Model (in russian)

46

Прерывание всплытия

• event.stopPropagation() –  Прерывает всплытие события по дереву

• event.stopImmediatePropagation() –  Прерывает всплытие события по дереву –  Отменяет прочие обработчики

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-stopPropagation

Page 47: JavaScript. Event Model (in russian)

47

Page 48: JavaScript. Event Model (in russian)

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

Page 49: JavaScript. Event Model (in russian)

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/

Page 50: JavaScript. Event Model (in russian)

debounce, throttle

Фильтрация событий

http://benalman.com/projects/jquery-throttle-debounce-plugin/

Page 51: JavaScript. Event Model (in russian)

Бывает, что событий очень много, а обрабатывать каждое дорого

Page 52: JavaScript. Event Model (in russian)

52

throttle

• Фильтрация частоты сообщений • Событие вызывается не чаще чем раз в N миллисекунд

Page 53: JavaScript. Event Model (in russian)

53

$.throttle(timeout, callback, no_trailing);

Page 54: JavaScript. Event Model (in russian)

54

$.throttle

no_trailing=false

no_trailing=true

Пауза

Пауза Поток событий

Допущенные события

Page 55: JavaScript. Event Model (in russian)

55

var log = $.throttle(250, function () { console.log(arguments); }); $(window).scroll(log); $(window).off('scroll', log);

$.throttle

http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/

Page 56: JavaScript. Event Model (in russian)

56

debounce

• Склеивает вызовы в один • Событие вызывается только после паузы в

N милисекунд

Page 57: JavaScript. Event Model (in russian)

57

$.debounce(timeout, callback, at_begin);

Page 58: JavaScript. Event Model (in russian)

58

$.debounce

at_begin=false

at_begin=true

Пауза

Пауза

Page 59: JavaScript. Event Model (in russian)

59

function suggest(event) {}; $('input').keyup(suggest); $('input').keyup($.debounce(250, suggest)); $('input').unbind('keyup', suggest);

$.debounce

http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/

Page 60: JavaScript. Event Model (in russian)

Неуместное использование Накладные расходы

Проблемы событий

Page 61: JavaScript. Event Model (in russian)

События это круто – давайте везде использовать!!1!

Page 62: JavaScript. Event Model (in russian)

62

Вариант не удачного использования событий

DataObject.on('someData', function (data) { console.log(data); }); DataObject.trigger('giveMe:someData');

Событие геттер

Page 63: JavaScript. Event Model (in russian)

63 DataObject.someData

Y U NO

Page 64: JavaScript. Event Model (in russian)

64

События – поток. Их лучше использовать как поток данных

Page 65: JavaScript. Event Model (in russian)

65

Module A Module B

Page 66: JavaScript. Event Model (in russian)

66

Module A Module B

Data C

Page 67: JavaScript. Event Model (in russian)

67

Module A Module B

Data C

Give me C

Page 68: JavaScript. Event Model (in russian)

68

Module A Module B

Data C

Data C'

Give me C

Page 69: JavaScript. Event Model (in russian)

69

Module A Module B

Data C

Data C'

Give me C

Page 70: JavaScript. Event Model (in russian)

70

Module A Module B

Data C Data C

Page 71: JavaScript. Event Model (in russian)

71

Накладные расходы

• Событие – функция –  n объектов, k ресурсов = n*k функций –  функция занимает ресурсы –  лишние скоупы, сборка мусора и JIT-компиляция –  вызов кучи функций –  утечки памяти

Page 72: JavaScript. Event Model (in russian)

Events everywhere!

Page 73: JavaScript. Event Model (in russian)

73

Не блокирующий I/O

• Дефрагментация времени блокировок –  Более плотная загрузка процесса

• Выгодно применять, когда время I/O больше времени обработки данных

• Меньше проблем с разделяемой памятью

Page 74: JavaScript. Event Model (in russian)

74

Слабое связывание

• Элементы не знают о программе • Элементы общаются только событиями • Меньше разделенной памяти

–  Меньше проблем синхронизации

Page 75: JavaScript. Event Model (in russian)

75

trigger(message)! on(message, callback)!

Page 76: JavaScript. Event Model (in russian)

76

Заключение

• События –  PubSub –  Event Emitter –  Event Manager

• Фичи событий –  namespace –  накопление данных

• DOM события –  Event Bubbling –  Делегирование –  Прерывание события –  Отмена действия по умолчанию

• Фильтрация

Page 77: JavaScript. Event Model (in russian)

77

Михаил Давыдов

Разработчик JavaScript

[email protected] azproduction

Спасибо