261N/A This example will illustrate how to use the synthetic event creation
261N/A API. We'll create an `arrow` event that fires in response
261N/A to the user pressing the arrow keys (up, down, left, right) and adds a
261N/A `direction` property to the generated event.
261N/A <p>Subscribing to this new event will look like this:</p>
261N/A Support will also be added for delegation, allowing a single subscriber
261N/A from a node higher up the DOM tree, to listen for the new event
261N/A emanating from its descendant elements.
261N/A<div class="example yui3-skin-sam">
261N/A {{>synth-example-source}}
261N/A<h2>`on`, `fire`, and `detach`</h2>
261N/A The three interesting moments in the lifecycle of a DOM event subscription
261N/A <li>The event is subscribed to</li>
261N/A <li>The event is fired</li>
<li>The event is unsubscribed from</li>
<em>config</em> )`. Define the implementation logic for the
`on` and `detach` moments in the configuration.
Typically the condition triggering the event firing is set up in the
on: function (node, sub, notifier) {
// what happens when a subscription is made
detach: function (node, sub, notifier) {
// what happens when a subscription is removed
In the case of arrow handling, the trigger is simply a key event with a
`keyCode` between 37 and 40. There are a few browser quirks with arrow
handling that warrant listening to `keydown` for some browsers and
`keypress` for others, so we'll take care of that transparently for `arrow`
on: function (node, sub, notifier) {
// Webkit and IE repeat keydown when you hold down arrow keys.
// Opera links keypress to page scroll; others keydown.
// Firefox prevents page scroll via preventDefault() on either
// Bummer to sniff, but can't test the repeating behavior, and a
// feature test for the scrolling would more than double the code size.
// To make detaching the associated DOM event easy, store the detach
// handle from the DOM subscription on the synthethic subscription
sub._detacher =
node.on(eventName, function (e) {
// Only notify subscribers if one of the arrow keys was pressed
// Add the extra property
// Firing the notifier event executes the arrow subscribers
// Pass along the key event, which will be renamed "arrow"
detach: function (node, sub, notifier) {
// Detach the key event subscription using the stored detach handle
<h2>Add Delegation Support</h2>
Since the `arrow` event is simply a filtered `keydown` or `keypress` event,
no special handling needs to be done for delegate subscriptions. We will
extract the key event handler and use it for both `on("arrow", ...)` and
`delegate("arrow", ...)` subscriptions.
// Webkit and IE repeat keydown when you hold down arrow keys.
// Opera links keypress to page scroll; others keydown.
// Firefox prevents page scroll via preventDefault() on either
_keyHandler: function (e, notifier) {
on: function (node, sub, notifier) {
// Use the extended subscription signature to set the 'this' object
// in the callback and pass the notifier as a second parameter to
sub._detacher =
node.on(this._event, this._keyHandler,
detach: function (node, sub, notifier) {
// Note the delegate handler receives a fourth parameter, the filter
// The filter could be either a string or a function.
delegate: function (node, sub, notifier, filter) {
sub._delegateDetacher =
node.delegate(this._event, this._keyHandler,
// Delegate uses a separate detach function to facilitate undoing more
// complex wiring created in the delegate logic above. Not needed here.
detachDelegate: function (node, sub, notifier) {
Subscribe to the new event or detach the event as you would any other DOM
// to prevent page scrolling
// See full code listing to show the data set up
case 'up':
xy.y -= 10; break;
case 'down':
xy.y += 10; break;
case 'left':
xy.x -= 10; break;
case 'right':
xy.x += 10; break;
// Subscribe using
node.on("arrow", ...);
Y.one("#A").on("arrow", move),
Y.one("#B").on("arrow", move)
subs =
Y.one('#demo').delegate('arrow', move, '.robot');
<h2>Bonus Step: to the Gallery!</h2>
Synthetic events are perfect candidates for Gallery modules. There are a
number already hosted there, and there are plenty of UI interaction
patterns that would benefit from being encapsulated in synthetic
The `arrow` event in this example is also
but with additional functionality. Check out
to see what you can do with synthetic events.
<h2>Full Code Listing</h2>
{{>synth-example-source}}