javascript. event model (in russian)

Post on 28-Nov-2014

303 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

TRANSCRIPT

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

JavaScript События

Паттерн PubSub

4

PubSub

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

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

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

5

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

PubSub – пример

6

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

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

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

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

Event Emitter

8

Event Emitter

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

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

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

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

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

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

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

11

Event Manager

12

Event Manager

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

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

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

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

13

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

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

Event Manager – пример

14

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

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

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

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

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

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

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

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

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

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

18

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

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

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

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

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

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

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

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

21

jQuery DOMReady

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

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

22

jQuery Ajax#done

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

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

DOM события

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

Event bubbling

Event capturing

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

24

Event bubbling

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

–  window или document

25

<div>

Event bubbling

<div> <div>

*Click*

26

<div>

Event bubbling

<div> <div>

*Click*

27

<div>

Event bubbling

<div> <div>

*Click*

28

<div>

Event bubbling

<div> <div>

*Click*

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

Функция 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

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

• 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

Особенности

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

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

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

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

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

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

34

<ul> onclick=delegateClick

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

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

<li class="bad">

35

<ul> onclick=delegateClick

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

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

<li class="bad">

36

<ul> onclick=delegateClick

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

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

<li class="bad">

37

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

38

<ul> onclick=delegateClick

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

<li class="good">

<li class="good">

<li class="bad"> *Click*

39

<ul> onclick=delegateClick

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

<li class="good">

<li class="good">

<li class="bad"> *Click*

40

<ul> onclick=delegateClick

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

<li class="good">

<li class="good">

<li class="bad"> *Click*

41

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

contains('good') === false;

42

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

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

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

43

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

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

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

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

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

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

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/

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

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

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

46

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

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

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

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

47

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

$('.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/

debounce, throttle

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

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

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

52

throttle

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

53

$.throttle(timeout, callback, no_trailing);

54

$.throttle

no_trailing=false

no_trailing=true

Пауза

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

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

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/

56

debounce

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

N милисекунд

57

$.debounce(timeout, callback, at_begin);

58

$.debounce

at_begin=false

at_begin=true

Пауза

Пауза

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/

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

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

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

62

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

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

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

63 DataObject.someData

Y U NO

64

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

65

Module A Module B

66

Module A Module B

Data C

67

Module A Module B

Data C

Give me C

68

Module A Module B

Data C

Data C'

Give me C

69

Module A Module B

Data C

Data C'

Give me C

70

Module A Module B

Data C Data C

71

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

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

Events everywhere!

73

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

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

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

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

74

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

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

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

75

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

76

Заключение

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

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

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

• Фильтрация

77

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

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

azproduction@yandex-team.ru azproduction

Спасибо

top related