index.mustache revision c967f42c8ecf9b590ab1a9fca4f5d5d905fc1ded
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<div class="intro">
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte The YUI Custom Event System enables you to define and use events beyond
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte those available in the DOM &mdash; events that are specific to and of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte interest in your own application. Custom Events are designed to work
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte much like DOM events. They can bubble, pass event facades, have their
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte propagation and default behaviors suppressed, etc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte </p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte The APIs for working with custom events are provided by the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte `EventTarget` class. All other infrastructure classes extend
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte `EventTarget`, but if you just need the custom event APIs, you can
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte `extend` or `augment` your classes with `EventTarget` directly.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte </p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <!--p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Bundled with `EventTarget` are <a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte href="http://en.wikipedia.org/wiki/Aspect_oriented_programming">Aspect
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Oriented Programming</a> methods that allow you to subscribe to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte execution of object methods, and
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli their own.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte </p-->
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik</div>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<!-- insert Events Evolved video here -->
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{{>getting-started}}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<h2>Video Overview</h2>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<iframe width="640" height="360" src="http://www.youtube.com/embed/s_7VjN3qxe8" frameborder="0" allowfullscreen></iframe>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte This video from YUIConf 2009 gives a good overview of the YUI event system
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte API. The content covers DOM and custom events. Note: the <a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte href="../event/index.html#synthetic-events">synthetic event</a> system was
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte updated since this video.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<h2>The Basics</h2>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte You can get started using custom events and the `EventTarget` API without
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte creating your own class. The YUI instance (typically `Y`) is an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte `EventTarget`, as is pretty much every other class in YUI. We'll go over
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte the basics using `Y`, then move into creating your own `EventTarget`s.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto If you've looked over the <a href="../event/index.html#the-basics">DOM
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Event system docs</a>, this should look very familiar. That's because
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `Node`s are also `EventTarget`s.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3>Subscribing to Events</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Custom events can have any name you want
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.on('anyOldNameYouWant', function () {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte alert("Looky there!");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Group subscriptions by passing an object or array to on()
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on({
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto somethingImportant: updateCalendar,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte birthday : eatCake,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte weekendEnd : backToTheGrindstone
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Some events have prefixes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.once("fuji:available", climb);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Custom events have distinct "after" moments
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.after("spa-category|pedicure", gelatoTime);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte All `EventTarget`s host methods
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="{{apiDocs}}/classes/EventTarget.html#method_on">`on`</a>,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="{{apiDocs}}/classes/EventTarget.html#method_once">`once`</a>,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="{{apiDocs}}/classes/EventTarget.html#method_after">`after`</a>, and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="{{apiDocs}}/classes/EventTarget.html#method_onceAfter">`onceAfter`</a>.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Both `once` and `onceAfter` will automatically detach the subscription
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte after the callback is executed the first time. All subscription methods
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return a subscription object called an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="{{apiDocs}}/classes/EventHandle.html">EventHandle</a>. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte distinction between `on` and `after` is discussed in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="#after">"after" phase</a> section below.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<h3 id="fire">Firing Events</h3>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// All subscribers to the myapp:ready event will be executed
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.fire('myapp:ready');
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Pass along relevant data to the callbacks as arguments
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.fire('birthday', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto name: 'Walt Disney',
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte birthdate: new Date(1901, 11, 5)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p id="event-data-object">
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Notify event subscribers by calling `fire( eventName )`, passing any
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto extra data about the event as additional arguments. Though `fire`
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto accepts any number of arguments, it is preferable to send all event data
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte in an object passed as the second argument. Doing so avoids locking your
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto code into a specific `fire` and callback signature.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Subscription callbacks receive fire() arguments
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('birthday', function (name, birthdate) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto var age = new Date().getFullYear() - birthdate.getFullYear();
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto alert('Happy ' + age + ', ' + name + '!');
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Possible, but not recommended
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.fire('birthday', 'A. A. Milne', new Date(1882, 0, 18));
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Instead, try to always pass only one object with all data
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('birthday', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto var age = new Date().getFullYear() - e.birthdate.getFullYear();
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto alert('Happy ' + age + ', ' + e.name + '!');
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.fire('birthday', {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte name: '"Uncle" Walt Whitman',
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto birthdate: new Date(1819, 4, 31)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte In the world of DOM events, the `fire` step is something the browser is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte responsible for. A typical model involves the browser receiving keyboard
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte input from the user and firing `keydown`, `keyup`, and `keypress` events.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Custom events put your code in the position of dispatching events in
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto response to criteria that are relavant to your objects or application.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3>Callback arguments and event facades</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Simple notification events don't send event objects, only fire() data
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('talkie', function (data) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto alert('(' + data.time + ') Walkie ' + data.message);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // data.preventDefault is not defined. data is just a plain object
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.fire('talkie', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto message: 'roger, over.',
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto time: new Date()
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Events configured to emitFacade will send an event object, merged with
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// fire() data
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.publish('bill:due', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto emitFacade: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto defaultFn : payUp
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('bill:due', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // Event facades have standard properties and methods as well as properties
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // from payload data passed to fire()
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (e.payee === 'Rich Uncle Sal') {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto e.preventDefault(); // the `payUp` method won't be called (Sal can wait)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto }
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Objects passed as the second argument to fire() for facade events will have
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// their properties merged onto the facade received by the callback.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.fire('bill:due', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto payee: 'Great Aunt Myra',
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto amount: 20
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Custom event callbacks are <em>usually, but not always</em> passed an
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <a href="{{apiDocs}}/classes/EventFacade.html">EventFacade</a> as their
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto first argument. Custom events can be configured to send event facades or
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto only the data they were fired with. <a href="#event-data-object">Always
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto passing event data in an object</a> as the second argument to `fire` allows
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto you to write all your callbacks to expect event data as a single first
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto argument, whether it's an `EventFacade` or just a plain object. The
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `emitFacade` and `defaultFn` configurations are detailed below, in
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <a href="#publishing-events">Publishing Events</a>.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3>Detaching Event Subscriptions</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Subscription methods return a subscription handle...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetovar subscription = Y.on('myapp:ready', initComponents);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// ...with a detach method
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesubscription.detach();
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Or detach by signature
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.detach('myapp:ready', initComponents);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Or by subscription category
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('spa-category|pedicure', gelatoTime);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Detach subscriptions to all events in the spa-category subscription group
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.detach('spa-category|*');
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte The preferred method of detaching subscriptions is to use the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="{{apiDocs}}/classes/EventHandle.html">EventHandle</a> that is
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto returned from the subscription methods. Alternately you can use the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="{{apiDocs}}/classes/EventTarget.html#method_detach">`detach` or
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `detachAll` methods</a> which work as described in the
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <a href="../event/index.html#detach-methods">Event user guide</a>.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3 id="extend-event-target">Extending EventTarget</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>Add the `EventTarget` APIs onto any class using `Y.augment()`.</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetofunction MyClass() {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* insert constructor logic here */
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto}
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoMyClass.prototype = {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto add: function (item) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // You can assume the APIs are available from your class instances
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.fire("addItem", { item: item });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto },
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Make MyClass an EventTarget
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.augment(MyClass, Y.EventTarget);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetovar instance = new MyClass();
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoinstance.on('addItem', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto alert("Yay, I'm adding " + e.item);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoinstance.add('a new item'); // ==> "Yay, I'm adding a new item"
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `Y.augment` works like a lazy `extend` or a mixin. It adds the APIs to the
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto host class, but on the first call to any of the methods, it calls the
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `EventTarget` constructor on the instance to make sure the necessary
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto internal objects are ready for use. If your class extends another,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto augmenting it won't interfere with that inheritance hierarchy.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `EventTarget`s can be set up with a number of default configurations for
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto the events they `fire`. Pass the defaults as the fourth argument to
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `Y.augment`.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Make all events fired from MyClass instances send an event facade
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.augment(MyClass, Y.EventTarget, true, null, {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto emitFacade: true
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h2>Publishing Events</h2>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Some custom event <a href="#configs">configurations can be defaulted</a>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto from class configuration, but others need to be specified on a per-event
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto basis. Use the `publish` method to do this.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// publish takes an event name and a configuration object
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.publish('somethingSpecial', {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte emitFacade: true,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte broadcast: 2,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto defaultFn: clapClapHallelujah,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto fireOnce: true
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3 id="facade">Event Facades</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto The most common configuration for custom events is `emitFacade`. This is
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto because with the event facades comes a lot of additional functionality,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto such as <a href="#defaultFn">preventable default behaviors</a> and <a
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto href="#bubbling">bubbling</a>.
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefunction Recipe() {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // publishing events is typically done at instantiation
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte this.publish('add', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto emitFacade: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto defaultFn: this._defAddFn
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto}
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Event facades mirror the event objects
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <a href="../event/index.html#facade-properties">you're familiar with from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte the DOM</a>. They have properties like `e.type` and `e.target` and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte the same methods, allowing you to call `e.preventDefault()` to disable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default behavior you've configured for the event or `e.stopPropagation()`
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte to stop the event from bubbling.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapallivar gruel = new Recipe();
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortegruel.on('add', function (e) {
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli if (e.item === "brussel sprouts") {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte // call e.preventDefault() just as you would for DOM events
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli e.preventDefault(); // brussel sprouts? eww!
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli }
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli `emitFacade` is typically passed as a default configuration to `Y.augment`.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto All other YUI infrastructure classes extend `EventTarget` and set
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `emitFacade` to `true` for you.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.extend(MyClass, Y.Base, {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto add: function (item) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // This will fire with an event facade because Y.Base sets emitFacade to true
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.fire('addItem', { item: item });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto },
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3 id="once">`fireOnce` Events</h3>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Important, typically system-level or lifecycle related events can be
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto configured as `fireOnce`. These events mimic things like `window.onload`
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto or the `domready` event.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoWidget.prototype.render = function (where) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // Widget rendering only happens once
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.publish('render', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto defaultFn: this._defRenderFn,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto fireOnce: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.fire('render', ...);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto After `fireOnce` events have been `fire()`d, any subsequent (late)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto subscriptions are immediately executed. This can introduce race
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conditions, however, since subscribers might expect to be called at a later
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto time, after the code that follows the subscription has also executed. In
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this case, you can configure `fireOnce` events with the `async` flag
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto and post-`fire` subscriptions will be executed in a `setTimeout`,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto allowing all subsequent code to run before the late subscriber is notified.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// BEFORE
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalliY.publish('myapp:ready', {
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli fireOnce: true
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli// ... elsewhere in the code
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// If myapp:ready has been fired, setStuffUp executes right now, but might
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// expect MyApp.Stuff to be created already. So, boom.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('myapp:ready', setStuffUp);
7b506e25917c371db526f76d85b9b1d17c8c5d39srivijitha dugganapalli
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoMyApp.Stuff = {};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// AFTER
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.publish('myapp:ready', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto fireOnce: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto async : true
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// ... elsewhere in the code
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Even if myapp:ready has been fired, setStuffUp will execute later. So, no boom
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('myapp:ready', setStuffUp);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoMyApp.Stuff = {};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3 id="bubbling">Bubbling Events</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Events that are configured with `emitFacade` support bubbling to other
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte `EventTarget`s, allowing you to subscribe to them from other objects, much
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte like DOM event bubbling. Add other `EventTarget`s to an instance's bubble
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte path with `addTarget`.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefunction LeafNode() { ... }
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoLeafNode.prototype.rename = function (newName) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto var oldName = this.name;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.name = newName;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.fire("update", {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto prevVal: oldName,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto newVal : newName
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefunction TreeNode() { ... }
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoTreeNode.prototype.add = function (node) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this._items.push(node);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // The new child node's events will bubble to this TreeNode
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto node.addTarget(this);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteY.augment(LeafNode, Y.EventTarget, true, null, { emitFacade: true });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.augment(TreeNode, Y.EventTarget, true, null, { emitFacade: true });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetovar rootNode = new TreeNode("ROOT"),
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto branchA = new TreeNode("branchA"),
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto leaf1 = new LeafNode("leaf1");
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetorootNode.add(branchA); // ROOT
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetorootNode.add( new LeafNode("leaf2") ); // / \
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // branchA leaf2
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetobranchA.add(leaf1); // / \
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetobranchA.add( new LeafNode("leaf3") ); // leaf1 leaf3
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Subscribe to 'update' events from any leaf or tree node under root
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForterootNode.on('update', function (e) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte alert(e.prevVal + " has been renamed " + e.newVal);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoleaf1.rename("Flower!"); // ==> "leaf1 has been renamed Flower!"
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3 id="prefix">Event Prefixes</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Individual events or all events fired by an `EventTarget` can be configured
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto to include a prefix to help filter subscriptions to common event names by
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto their origin. Prefixed event names look like `'prefix:eventName'`.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Taking the <a href="#bubbling">code snippet above</a>, configuring a default
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte `prefix` while augmenting the classes will allow for subscription to
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto only `LeafNode` updates.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// All events fired by LeafNode instances will be prefixed with "leaf:"
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.augment(LeafNode, Y.EventTarget, true, null, {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto emitFacade: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto prefix: 'leaf'
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// ...and for TreeNodes, "tree:"
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.augment(TreeNode, Y.EventTarget, true, null, {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto emitFacade: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto prefix: 'tree'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Listen specifically for changes from LeafNodes
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetorootNode.on('leaf:update', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto alert(e.prevVal + " has been renamed " + e.newVal);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoleaf1.rename("Flower!"); // ==> "leaf1 has been renamed Flower!"
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetobranchA.rename("Chewbacca!"); // (nothing)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Subscribing with prefixes is similar to
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <a href="../event/delegation.html">using DOM event delegation</a>, though it
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto is done using `on()` rather than `delegate()`.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Optionally, you can omit the prefix when subscribing on the object that
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto fires the event.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// prefix is optional when subscribing on the firing object...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoleaf1.on('leaf:update', worksJustLike);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoleaf1.on('update', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto e.type; // 'leaf:update' -- the event type will remain prefixed
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// ...but prefixes are required from other objects
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetorootNode.on('update', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // will not capture leaf:update events
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Subscribe to all events of a specific type, regardless of prefix, using the
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto wildcard prefix `*:eventName`.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Execute the callback if either the group object or one of its items fires an
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// `update` event
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetorootNode.on('*:update', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto switch (e.type) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto case "leaf:update": ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto case "tree:update": ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto }
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3 id="defaultFn">Adding Default Behavior</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Custom events can be bound to behaviors just like DOM events (e.g. clicking
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto on a link causes navigation to a new page). This is especially useful when
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte doing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte operations that you want to expose to other objects in your system to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte prevent, alter, or enhance.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Add a default behavior to an event by configuring the event's `defaultFn`.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte By convention, default functions are named `_def(the name of the event)Fn`.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetofunction TreeNode(name) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.name = name;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this._items = [];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // Event publishing is typically done during instantiation
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.publish('add', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto defaultFn: this._defAddFn
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto}
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Adding a child node is an interesting mutation operation. Move the mutation
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// logic from the method to a mutation event's default behavior
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoTreeNode.prototype.add = function (node) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.fire('add', { newNode: node });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Default functions receive the event facade like other subscribers
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoTreeNode.prototype._defAddFn = function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this._items.push(e.newNode);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto e.newNode.addTarget(this);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetobranchA.add(leaf1); // without 'add' subscriptions, the behavior is the same
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Unless configured with `preventable: false`, default behaviors can be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte disabled with `e.preventDefault()` just like the DOM. Unlike their DOM
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto counterparts, though, event subscribers <em>can change facade
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto properties</em> to alter the default behavior by way of effectively changing
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto its input.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForteTreeNode.prototype.add = function (node) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte this.fire('add', {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto newNode: node,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto bubbleEvents: true
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte// Default functions receive the event facade like other subscribers
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoTreeNode.prototype._defAddFn = function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this._items.push(e.newNode);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (e.bubbleEvents) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte e.newNode.addTarget(this);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto};
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// You can prevent default behavior from anywhere along the bubble path
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetorootNode.on('tree:add', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (e.newNode.name === "Leafy") {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto e.preventDefault();
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto } else if (e.newNode.name === "James Bond") {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto e.bubbleEvents = false; // Shhhh
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte});
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForterootNode.add( new LeafNode("Leafy") ); // Node NOT added
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn ForterootNode.add( new LeafNode("James Bond") ); // Node added without event bubbling
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<h3>Broadcasting Events to Y or Between YUI instances</h3>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Event broadcasting is very similar to bubbling, but with some important
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte distinctions:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<ol>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <li>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte Broadcasting is specific to the YUI instance and the `Y.Global` shared
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte `EventTarget`
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte </li>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <li>Events don't need to be configured with `emitFacade` to broadcast</li>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <li>Broadcasting happens after the default behavior, which also means...</li>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <li>Event behavior can't be prevented from broadcast subscribers</li>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte <li>Broadcast can be defaulted for all events for an `EventTarget`</li>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte</ol>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Broadcasting is essentially a "fast track" bubbling configuration allowing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte you to specify that events can be subscribed to from the YUI instance (with
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `broadcast: 1`) or from `Y.Global` (with `broadcast: 2`).
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// All events from instances of MyClass can be subscribed from Y.on()
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.augment(MyClass, Y.EventTarget, true, null, {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto emitFacade: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto prefix: 'awesome',
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto broadcast: 1
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto// Respond to a 'thing' event from any instance of MyClass in the YUI sandbox
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoY.on('awesome:song', partyOn);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetovar instance = new MyClass()
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoinstance.fire("song", { which: "Bohemian Rhapsody", whom: "Wayne" });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `Y.Global` is an `EventTarget` that is shared between all YUI instances,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto allowing cross-sandbox communication. To avoid feedback loops, it's best
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto to add an instance identity to outgoing events and only respond to
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto incoming events from other identities.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoYUI().use('node', 'event-custom', function (Y) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte var id = "Alpha Beta Base"; // probably Y.guid() would be safer
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // Stamp outgoing messages with this instance's id
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Y.on('*:message', function (e) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto e.originInstance = id;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Y.Global.on('*:message', function (e) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (e.origin !== id) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto alert("message received from " + e.origin + ": " + e.message);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto function Character() {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto this.publish('message', { broadcast: 2 });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto }
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Y.augment(Character, Y.EventTarget, true, null, {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte emitFacade: true,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto prefix: ''
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte });
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte var murdock = new Character();
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Y.one('#status').on('click', function () {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto murdock.fire("message", {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte message: "You're coming in too fast!"
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoYUI().use('event-custom', function (OtherY) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto var id = "Lunar Shuttle";
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto // ...(the same setup as above)...
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto var striker = new Character()
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Y.one('#status').on('click', function () {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto striker.fire("message", {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto message: "She's beginning to crack up"
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto });
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto});
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto```
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<!--h3>Monitoring Events</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>TODO</p-->
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<h3 id="configs">Available Event Configurations and Defaults</h3>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<p>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto Events can be configured with the following properties. Properties marked
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto as "Class Configurable" can be passed to the `EventTarget` constructor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte configuration to default for all events.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</p>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<table>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<thead>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <tr>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <th>Configuration</th>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <th>Description</th>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <th>Default</th>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <th>Class Configurable?</th>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto </tr>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto</thead>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto<tbody>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <tr>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>`prefix`</td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto `e.type` will always include the configured prefix.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <a href="#prefix">Details above</a>.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto </td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>(empty)</td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>YES</td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto </tr>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <tr>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>`context`</td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto The default `this` object to execute callbacks with. Rarely set.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto </td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>The instance</td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto <td>YES</td>
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto </tr>
<tr>
<td>`emitFacade`</td>
<td>
If `true`, sends event facades to callbacks, allows bubbling and
default functions, etc. This is commonly set to true for a class.
<a href="#facade">Details above</a>.
</td>
<td>`false`</td>
<td>YES</td>
</tr>
<tr>
<td>`fireOnce`</td>
<td>
If `true`, events will only fire once. Subscriptions made after
firing will be immediately executed.
<a href="#once">Details above</a>.
</td>
<td>`false`</td>
<td>YES</td>
</tr>
<!--tr>
<td>`monitored`</td>
<td>
Allows you to subscribe to the event lifecycle moments (publish,
fire, and subscribe) as separate events.
<a href="#monitor">Details above</a>.
</td>
<td>`false`</td>
<td>YES</td>
</tr-->
<tr>
<td>`broadcast`</td>
<td>
Notify the YUI instance (`broadcast: 1`) or the YUI instance
<em>and</em> `Y.Global` with the event.
<a href="#broadcast">Details above</a>.
</td>
<td>0 (instance only)</td>
<td>YES</td>
</tr>
<tr>
<td>`bubbles`</td>
<td>
For events configured to `emitFacade` allow bubbling events to
other `EventTarget`s.
</td>
<td>`true`</td>
<td>YES</td>
</tr>
<tr>
<td>`defaultFn`</td>
<td>
Behavior associated with the event. Usually this is preventable
(see `preventable` below). <a href="#defaultFn">Details above</a>.
</td>
<td>(none)</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>`preventable`</td>
<td>
If set to `false`, `e.preventDefault()` will not disable execution
of the event's `defaultFn`.
</td>
<td>`true`</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>`preventedFn`</td>
<td>
<p>
Behavior associated with the event when `e.preventDefault()` is
called from a subscriber. Use this function to reset partially
applied transactional state.
</p>
<p>Incompatible with `preventable: false`.</p>
</td>
<td>(none)</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>`stoppedFn`</td>
<td>
Behavior associated with the event when `e.stopPropagation()` is
called from a subscriber. Seldom used.
</td>
<td>(none)</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>`async`</td>
<td>
Only applicable to events also configured with `fireOnce: true`.
If `true`, new subscriptions to this event after it has already
been fired will be queued to execute in a `setTimeout` instead of
immediately (synchronously).
</td>
<td>false</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
<h3 id="after">The "after" phase</h3>
<p>
Unlike DOM events, custom events also expose an "after" phase that
corresponds to the time immediately after an event's <a
href="#defaultFn">default behavior</a> executes. Subscribe to an event's
"after" phase with the `after(...)` method. The signature is the same as
`on(...)`.
</p>
```
rootNode.after('tree:add', calc.updateTotals, calc);
```
<p>
The primary benefit of using `after()` subscriptions over `on()`
subscriptions is that if any `on()` subscribers call `e.preventDefault()`,
neither the event's configured `defaultFn` <em>nor the `after()`
subscribers</em> will be executed. If an `after()` subscription is
executed, you know that the `defaultFn` did as well.
</p>
<p>
<strong>Use `after()` to subscribe to events with a default behavior when
you want to react to the event with a side effect.</strong>
</p>
<p>
<strong>Use `on()` to subscribe to events if you need to prevent or alter
the default behavior or if they don't have default behavior.</strong>
</p>
<h2>Event Lifecycle</h2>
<p>The order of operations when firing an event is as follows:</p>
<h3 id="simple-event-lifecycle">Simple Events (no facade)</h3>
<ol>
<li>`on()` subscribers are executed</li>
<li>`after()` subscribers are executed</li>
<li>`Y.on()` broadcast subscribers are executed.</li>
<li>`Y.after()` broadcast subscribers are executed.</li>
<li>`Y.Global.on()` broadcast subscribers are executed.</li>
<li>`Y.Global.after()` broadcast subscribers are executed.</li>
</ol>
<p>
If an `on()` or `after()` subscriber returns `false`, no more subscribers
will be notified.
</p>
<h3 id="complex-event-lifecycle">Complex Events (with facade)</h3>
<ol>
<li>`on()` subscribers are executed</li>
<li>
`on()` subscribers for each bubble target and their respective targets
are executed until all targets' bubble paths are walked or a subscriber
stops the propagation of the event.
</li>
<li>
If the event was prevented, any configured `preventedFn` will execute.
</li>
<li>If not prevented, any configured `defaultFn` will execute.</li>
<li>If bubbling was stopped, any configured `stoppedFn` will execute.</li>
<li>`Y.on()` broadcast subscribers are executed.</li>
<li>`Y.after()` broadcast subscribers are executed.</li>
<li>`Y.Global.on()` broadcast subscribers are executed.</li>
<li>`Y.Global.after()` broadcast subscribers are executed.</li>
<li>`after()` subscribers are executed.</li>
<li>
`after()` subscribers for each bubble target and their respective
targets are executed.
</li>
</ol>
<p>
The flow can ben interrupted by `on()` subscribers doing any of these
things:
</p>
<dl>
<dt>`e.preventDefault()`</dt>
<dd>
<ol>
<li>The `defaultFn` will not be executed</li>
<li>The `preventedFn` will execute</li>
<li>No `after()` subscriptions will be executed</li>
</ol>
</dd>
<dt>`e.stopPropagation()`</dt>
<dd>
<ol>
<li>The remainder of subscribers at this `EventTarget` <strong>WILL</strong> execute</li>
<li>No bubble targets of this `EventTarget` will be notified</li>
<li>The `stoppedFn` will execute</li>
<li>The `defaultFn` and `after()` subscribers will execute</li>
</ol>
</dd>
<dt>`e.stopImmediatePropagation()`</dt>
<dd>
Same as `e.stopPropagation()` except no more subscribers at this
`EventTarget` will execute.
</dd>
<dt>`e.halt()`</dt>
<dd>
Same as `e.preventDefault()` plus `e.stopPropagation()`.
</dd>
<dt>`e.halt(true)`</dt>
<dd>
Same as `e.preventDefault()` plus `e.stopImmediatePropagation()`.
</dd>
<dt>`return false`</dt>
<dd>Same as `e.halt(true)`. Not recommended. Use the API methods.</dd>
</dl>
<!--h2 class="no-toc">Subscribing to Object Methods with `Y.Do.*`</h2>
<h3 class="no-toc">Before and After</h3>
<h3 class="no-toc">Altering the Wrapped Method Behavior</h3>
<h3 class="no-toc">`EventTarget` API methods</h3>
<p>
TODO
</p-->