События
6.1.4.2. Источники событий и наблюдатели в JavaScript
Обработчики событий можно задать с помощью XML-атрибута или с помощью JavaScript-метода, основываясь на DOM-стандартах. Оба подхода продемонстрированы в листинге 6.5. Это верно и для источников данных и наблюдателей Mozilla. Однако сходство действительно, только если используется XUL. В листинге 6.11 сравниваются техники создания пар "источник событий - наблюдатель" с помощью XUL и JavaScript.
<!-- XML-вариант --> <broadcaster id="bc"/> <box id="x1" observes="bc" onbroadcast="execute(this)"/> // AOM-вариант <broadcaster id="bc"/> <box id="x1"/> var bc = getElementById("bc"); var x1 = getElementById("x1"); addBroadcastListenerFor(bc, x1, "foo"); addEventListener("broadcast", execute, false); // также removeBroadcastListenerFor(bc, x1, "foo");Листинг 6.11. Связывание источников событий и наблюдателей,с использованием XUL или JavaScript
Оба эти примера создают отношение "источник событий-наблюдатель" между двумя тегами. Новый метод addBroadcasterListenerFor() объекта XUL-окна создает связь в случае JavaScript. Обратите внимание, что подписчик onbroadcast также нужно задать.
6.1.4.3. Источники событий и наблюдатели в XPCOM
Как и таймеры, источники событий и наблюдатели можно создавать быстро, в стиле web-разработки, с помощью XUL, или медленнее, но более гибко - с помощью XPCOM-компонентов. В листинге 6.7 продемонстрировано частичное использование XPCOM-компонентов. Вспомним, что объект observer явно следует шаблону наблюдателя и что объект nsITimer - в некотором роде источник событий, хотя и ограничен для данного отложенного события только одним наблюдателем.
Листинг 6.7 можно изучить дальше. На рисунке 6.2 показан вывод единственного вызова alert() в этом примере.
Три аргумента, передаваемые методу observe(), отображены в этом окне. Ранее мы не обращали на них внимания, но теперь их можно рассмотреть.
Третий аргумент - это данные, связанные с событием. nsITimer не предоставляет никаких данных для этого аргумента.
Второй аргумент - эквивалент атрибута attribute XUL-тега <observes>. Он указывает, какое событие имеет место. Значение timer-callback - особое значение, связанное с XPCOM-событием nsITimer. Это значение указано в C/C++-коде Mozilla, но это нестандартное событие DOM.
Первый аргумент - сам объект nsITimer. В окне сообщения он был приведен к JavaScript-типу String. Единственный способ сделать это - вызвать для объекта метод toString(). Так что наблюдатель в данном примере выполняет действие над источником данных, чтобы просто получить строку. Это пример активного взаимодействия объектов и источников данных. На самом деле наблюдатель может обращаться к любому свойству источника данных, а не только к методу toString().
В Mozilla есть и более общая, чем nsITimer, поддержка систем "источник данных-наблюдатель". Простейший наблюдатель:
@mozilla.org/xpcom/observer;1 interface nsIObserver
Это "ничего не делающий" наблюдатель, немного похожий на /dev/null. Его метод observe() просто сообщает об успешном завершении. В Mozilla есть множество специализированных компонентов для наблюдателей, вы также можете создать свой, как показано в листинге 6.7. Источник событий в XPCOM Mozilla более полезен. Он основывается на паре:
@mozilla.org/observer-service;1 interface nsIObserverService
Такой единственный объект - обобщенный источник событий. Он будет уведомлять любые объекты-наблюдатели, подписавшиеся на оповещения, независимо от того, какому окну принадлежит наблюдатель. В листинге 6.12 приведен пример типичного применения этого компонента.
var observer = { ... as in Listing 6-6 ... }; var observer2 = { ... another observer ... ); var CC = Components.classes, CI = Components.interfaces; var cls, caster; cls = CC["@mozilla.org/observer-service;1"]; caster = cls.getService(CI.nsIObserverService); caster.addObserver(observer, "my-event", true); caster.addObserver(observer2, "my-event", true); caster.notifyObservers(caster, "my-event", "anydata");Листинг 6.12. Пример XPCOM-пары "источник данных-наблюдатель"
Объект caster - единственный источник событий. При добавлении наблюдателей с помощью addObserver() первый аргумент - объект наблюдателя, второй - строка события для наблюдателя, третий - флаг, сообщающий, написан ли наблюдатель на JavaScript. Если это так, следует использовать true. Если это XPCOM-компонент, написанный на C/C++, нужно указывать false. notifyObservers() создает событие данного типа; третий аргумент тут - любые данные, которые могут быть аргументами или параметрами события. Эти данные будут получены объектами наблюдателей.
На этом введение в источники событий и наблюдатели Mozilla заканчивается.
6.1.5. Команды
Четвертая система событий, упоминаемая в этой лекции, связана с командами. В Mozilla команда - действие, которое может быть выполнено приложением. Переход по ссылкам и отправка форм в HTML - неточный эквивалент задач, реализуемых командами Mozilla.
Хотя простейшее представление команды - одна функция на JavaScript, это не единственный вариант. Команда также может быть сообщением из одного места в другое. Этот аспект делает команды в Mozilla очень похожими на события. Другие примеры "событийного" поведения появляются поверх базовой системы команд: когда состояние команд меняется, об этом рассылаются уведомления.
В целом система команд в Mozilla довольно сложна. В "Команды" , "Команды", эта система рассматривается не только в контексте целого окна XUL, но и исследуются ее составляющие. Сейчас просто следует запомнить, что система команд Mozilla - расширение или дополнение модели обработки событий DOM 3.
6.1.6. События доставки данных
Последняя система событий ввода Mozilla, рассматриваемая в этой лекции - система доставки данных. Эта система ответственна за принятие URL и возврат соответствующего ему документа или за отправку почтовых сообщений. Это многопрофильная система с несколькими вариантами применения.
События DOM, таймера и наблюдателей - все они имеют дело с маленькими порциями данных. Совершающееся событие может представлять какой-либо другой, больший процесс обработки где-то в платформе Mozilla, но сами данные события обычно невелики по объему. Эти события можно назвать легковесными.
События доставки данных, по сравнению с описанными выше, обычно большие. Это может быть загрузка электронной почты или загрузка файла на FTP-сервер, или обновление конференции. Более того, такие события могут разбиваться на более мелкие события: отдельные почтовые сообщения, часть файла, загруженная уже на сервер, отдельные заголовки сообщений конференции. Во время работы с такими событиями между поставщиком и потребителем возникают более длительные отношения, которые не заканчиваются, пока последняя часть работы не будет завершена.
У такой сложной системы событий есть собственный язык. Поставщики здесь называются источниками данных или информации; потребители называются адресатами данных или просто адресатами. Более подробное обсуждение источников и потребителей данных мы отложим до "Объекты XPCOM" , "Объекты XPCOM".
Рассмотрев внутреннюю обработку событий в Mozilla, мы теперь можем посмотреть, как такие события может создавать пользователь.