index.mustache revision 42f04b06465678a6d795fc4c3aa4bcc5aa8bfda8
<style>
h4 code {
text-transform: none;
}
</style>
<div class="intro component">
<p>The YUI Event Utility provides APIs for working with the browser's DOM
event system. It simplifies tasks like subscribing to button `click`s or
canceling &lt;form&gt; `submit`s to, for example, allow sending data to the
server via ajax.</p>
<p>In addition, the "Synthetic event" system supplies <em>entirely new</em>
DOM events to subscribe to as well as fixing events that behave differently
across browsers. Implementers can create their own DOM events triggered by
specific user actions or other environmental criteria.</p>
<p>The API for working with DOM events is provided by the EventTarget class,
which also services the Custom event infrastructure that is used throughout
YUI. Read more about working with custom events <a
href="../event-custom/">in the EventTarget user guide</a>.</p>
</div>
{{>getting-started}}
<h2>The Basics</h2>
<h4>Listening for events</h4>
```
// Step 1. Capture a button node
var button = Y.one("#readygo");
// Step 2. Subscribe to its click event with a callback function
button.on("click", function (e) {
// Step 3. do stuff when the button is clicked
});
```
<p><code>on(<em>type</em>, <em>callback</em>)</code> is the main common
subscription method, and is available on every <a href="../node/">`Node`</a>
and <a href="../node/#nodelist">`NodeList`</a>.</p>
<p>Replace "click" with <a href="#event-whitelist">any other event name</a> to subscribe to that event.</p>
<h4>The Callback and the Event Object</h4>
```
button.on('click', function (e) {
// `this` is the button Node, NOT the DOM element
this.get('id'); // ==> 'readygo' (from <button id="readygo">...</button>)
// Event properties that point to the DOM are also Node instances
e.target.get('id'); // => 'readygo'
// Stop the event's default behavior
e.preventDefault();
// Stop the event from bubbling up the DOM tree
e.stopPropagation();
});
```
<p>Subscribed callbacks are passed a <a href="#facade-properties">a normalized
event object</a> as their first argument.</p>
<p>The keyword "`this`" in the callback will refer to the Node or NodeList
that you subscribed from.</p>
<h4>`e.preventDefault()` and `e.stopPropagation()`</h4>
<p>Many events have a default behavior, such as the `submit` event serializing
form data and making a new page request. Disable this behavior with
`e.preventDefault()`.</p>
```
function setFilter(e) {
// Stop the link from loading the href page
e.preventDefault();
// Now do my own thing instead
var url = this.get('href').replace(/page/, 'partial');
Y.one('#contentArea').load(url);
// `return false` is supported, but not preferred. use e.preventDefault()
return false;
}
Y.one('#table-filter-link').on('click', setFilter);
```
<p>Most events can be listened for on the specific element that originates them
<em>or from any of their parent elements</em>, all the way up to the
`document`. Prevent dispatching the event to subscriptions bound to elements
further up the DOM tree with `e.stopPropagation()`. In practice, this is
rarely useful.</p>
<p>Returning `false` from a callback will also stop the propagation of the
event, which may cause unintended side effects.</p>
<p>`e.stopPropagation()` won't prevent the execution of other subscribers
listening to the same element, only elements further up the DOM tree. If you
need to stop all execution, use `e.stopImmediatePropagation()` or
`e.halt(true)`. The latter will also call `e.preventDefault()`.</p>
<h4>Detaching subscriptions</h4>
<p>`node.on()` and all
<a href="#more-options">other subscription methods</a> return a
subscription object that can be used to unbind that subscription. Node also
supports a `detach()` method and <a href="#detach-methods">other ways to cleaup
subscriptions</a>.</p>
```
// on() returns a subscription handle...
var sub = button.on("click", handleClick);
// ...that can be used to unbind the subscription
sub.detach();
// Alternately, use the Node's detach() method
button.detach("click", handleClick);
```
<p>Just this should take care of most of the simple event bindings you'll need.
There's [[#More Options|a lot more you can do]], though, so read on!</p>
<h2 id="modules">What to `use()`</h2>
<p>Before we get into more API goodies, let's talk about the Event Utility's module breakdown.</p>
<p>For starters, in most cases <em>you probably won't
`use('event')`</em>. The core DOM event system ("event-base") is required by
the "node-base" module, which itself if required by just about everything in
YUI. So you probably already have the DOM event API and didn't know it!</p>
<p>Here is the full breakdown of modules in the DOM event system:</p>
<table>
<thead>
<tr>
<th>`use("______", ...)`</th>
<th>What's in it?</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="{{apiDocs}}/module_event-base.html">`event-base`</a></td>
<td>
The Core DOM event subscription system as well as the DOM lifecycle
events <a href="domready.html">`domready`, `contentready`, and
`available`</a>. Notably, it does NOT include
<ul>
<li>event delegation</li>
<li>event simulation</li>
<li>synthetic events</li>
</ul>
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event.html">`event`</a></td>
<td>
A rollup of all modules below except
<ul>
<li>"event-simulate"</li>
<li>"node-event-simulate"</li>
<li>"node-event-delegate" (which is in the "node" rollup)</li>
</ul>
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-delegate.html">`event-delegate`</a> &amp;
<br>
<a style="white-space: nowrap;" href="{{apiDocs}}/module_node-event-delegate.html">`node-event-delegate`</a></td>
<td>
Adds the `Y.delegate(...)` and `node.delegate(...)` methods,
respectively, for [[#Event Delegation|event delegation]] convenience.
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-simulate.html">`event-simulate`</a></td>
<td>
<p>Adds APIs for triggering native DOM events for unit testing.</p>
<p><strong>Note: <a href="#faking">Faking DOM events should not be
used in user facing code</a></strong>.</p>
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-synthetic.html">`event-synthetic`</a></td>
<td>
<p>Supplies the infrastructure for creating new DOM events, "fixing"
existing events with undesirable or inconsistent behavior, and
<a href="synths.html">all sorts of other things</a>.</p>
<p>All of the modules below are synthetics.</p>
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-flick.html">`event-flick`</a></td>
<td>
Adds a <a href="touch.html#flick">"flick" event</a> for touch or
mouse interaction.
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-focus.html">`event-focus`</a></td>
<td>
<a href="focus.html">Fixes `focus` and `blur` events</a> to bubble
(for delegation).
</td>
</tr>
<td><a href="{{apiDocs}}/module_event-gestures.html">`event-gestures`</a></td>
<td>
<p>A rollup of the following modules:</p>
<ul>
<li>"event-touch"</li>
<li>"event-move"</li>
<li>"event-flick"</li>
</ul>
<p>In the future, may contain more gesture abstraction modules.</p>
</td>
<tr>
<td><a href="{{apiDocs}}/module_event-hover.html">`event-hover`</a></td>
<td>
Adds a <a href="mouseenter.html">"hover" event</a> which binds to
two callbacks, one for the start, and one for the end of a mouse
hover.
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-key.html">`event-key`</a></td>
<td>
Adds a <a href="key.html">"key" event</a> which listens for
specific, implementer defined, keys being pressed by the user.
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-mouseenter.html">`event-mouseenter`</a></td>
<td>
Adds <a href="mouseenter.html">"mouseenter" and "mouseleave"
events</a>. You probably want to use these instead of "mouseover"
and "mouseout".
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-mousewheel.html">`event-mousewheel`</a></td>
<td>
<p>Adds a "mousewheel" event for monitoring users scrolling the
window with the mousewheel. Event facades passed to the callback
will have an `e.wheelDelta` property corresponding to the amount of
scrolling.</p>
<p>Currently, this event can only be subscribed with
`Y.on("mousewheel", callback)`;</p>
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-move.html">`event-move`</a></td>
<td>
Adds <a href="touch.html#move">"gesturemovestart", "gesturemove",
and "gesturemoveend" events</a> that serve as abstractions over
mouse and touch events, forking internally based on the client
device.
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-outside.html">`event-outside`</a></td>
<td>
Adds a <a href="outside.html">"clickoutside" and several other
___outside events</a> to trigger behavior based on actions taken
outside a specific element.
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-resize.html">`event-resize`</a></td>
<td>
<p>Adds a "windowresize" event that only fires after a user has
stopped dragging a window's resize handle. This normalizes the
`window.onresize` event across browsers.</p>
<p>This event can only be subscribed with
`Y.on("windowresize", callback)`;</p>
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-touch.html">`event-touch`</a></td>
<td>
Adds support for <a href="touch.html">subscribing to native touch
and gesture events</a>.
</td>
</tr>
<tr>
<td><a href="{{apiDocs}}/module_event-valuechange.html">`event-valuechange`</a></td>
<td>
Adds a <a href="valuechange.html">"valueChange" event</a> that fires when input element text
changes (this is harder than you think).
</td>
</tr>
</tbody>
</table>
<h2>Event Delegation</h2>
<p>If you don't already know what event delegation is, you should <a
href="delegation.html">read this quick overview</a>. Short form: <em>you need
to be using this</em>.</p>
```
// single element subscription
node.on("click", handleClick);
// delegated subscription for all button clicks from inside the node
node.delegate("click", handleClick, "button, input[type=button]");
```
<p>Creating a delegated subscription looks very much like creating any other
event subscription with two differences. First, it's a different method name,
`delegate`. Second, there is another argument: a CSS selector that is used to
test the event's originating element to decide if the callback should be
executed. If the event started at or inside an element matching the selector,
the callback will execute.</p>
<p>Unlike `node.on()` subscriptions, the `this` object in `node.delegate()`
callbacks will refer to the element that matched the css filter, not to `node`.
We did this because likely your logic revolves around the nodes described by
the filter, not around the element that contains them.</p>
```
function handleClick (e) {
// `this` is the button with class .remove, not the #items element
// remove the containing LI
this.ancestor('li').remove();
// e.currentTarget is also the button.remove
// e.container === Y.one('#items')
}
Y.one('#items').delegate('click', handleClick, 'button.remove');
```
<p>For more complex target filtering, a function can be passed instead of a css
selector. See the
<a href="{{apiDocs}}/module_event-delegate.html#method_delegate">API docs</a>
for more details.</p>
<p>As noted <a href="modules">above</a>, the `event-delegate` module is
included in the `event` rollup, but `node-event-delegate` isn't. We recommend
using delegation from the Node API, so you should `use()` either
`node-event-delegate` or the `node` rollup.</p>
<h2>More Options</h2>
<h4>Subscribe from `Y`</h4>
```
// Y.on() takes a third argument which is the Node, DOM element,
// or CSS selector of the element(s) to bind
Y.on("click", handleClick, "#readygo");
// Y.delegate() similarly takes the containing element or selector
// as the third argument
Y.delegate("click", handleClick, "#container", "button, input[type=button]");
```
<p>An alternate syntax for DOM subscriptions is using `Y.on()` or
`Y.delegate()`. When identifying the target by a CSS selector, these methods
can be used regardless if the element is currently available for scripting. If
it's not yet on the page, a poll will regularly look for it (for a few seconds)
and the subscription will be automatically attached when the element is
found. Relying on this behavior can introduce race conditions, though, so use
it wisely. Otherwise, use of `node.on()` or `Y.on()` is a stylistic
preference.</p>
<h4 id="once">One time subscriptions</h4>
```
tabLabel.once('mouseover', loadTabContent);
```
<p>If you only want to execute a callback on the first occurrence of an event, use `node.once()` or `Y.once()`. The subscription will be automatically detached after the event fires.</p>
<p>The signature for `once()` is the same as that for `on()`.</p>
<h4>Grouping subscriptions</h4>
<p>Pass an object to subscribe to multiple events, each with their own
callback</p>
```
var groupSub = inputNode.on({
blur: validate,
keypress: validate,
focus: clearPlaceholder
});
// Detach the blur, keypress, and focus subscriptions in one call
groupSub.detach();
```
<p>Pass an array to subscribe to multiple events with the same callback</p>
```
groupSub = inputNode.on(['focus', 'mouseover'], activate);
// Detach the focus and mouseover subscriptions
groupSub.detach();
```
<p>Prefix the event name with a category to allow detaching multiple
subscriptions by that category.</p>
```
inputNode.on('my-category|focus', activate);
inputNode.on('my-category|mouseover', activate);
// You can detach specific subscriptions by 'my-category|focus' or all with |*
inputNode.detach('my-category|*');
```
<p>The `once()` and `delegate()` methods also support these alternate
signatures.</p>
<h4 id="extended-signature">Binding `this` and additional callback arguments</h4>
<p>By default, the "`this`" object in subscription callbacks will be the Node
or NodeList that subscribed to them. Override this default by passing your own
`this` object as the third argument to `node.on()` or the fourth to
`node.delegate()`. Note that the argument index is shifted when using `Y.on()`
and `Y.delegate()` or synthetic events with custom signatures.</p>
```
// equivalent to node.on('click', function (e) { overlay.hide(e); });
node.on('click', overlay.show, overlay);
node.once('mouseover', door.unlock, door);
// `this` override comes after the filter; also shifted for the 'key' event's
// custome signature.
container.delegate('key', validator.isValid, 'enter,tab', 'input', validator);
// Corresponding alternatives from Y
Y.on('click', overlay.show, '#show', overlay);
Y.once('mouseover', door.unlock, '#gate13', door);
Y.delegate('click', validator.isValid, '#myForm', 'enter,tab', 'input', validator);
```
<p>Additional arguments passed to the subscription methods will be sent along
to the callback after the event facade. If you want to bind extra arguments,
but don't want to override the "`this'" object, pass `null` for the `this`
argument.</p>
```
```
<h4>More ways to clean up subscriptions</h4>
<h2>Event Simulation</h2>
<h2>Synthetic Events</h2>
<p>The event system supports adding new abstractions over the native DOM
environment that behave like DOM events. These abstractions are called
synthetic events, and you can subscribe to them like any other DOM event with
`node.on()` or `node.delegate()`.</p>
```
Y.one('#dialog').on('clickoutside', function (e) {
this.transition('fadeOut');
});
Y.one('#editable-table').delegate('key', saveAndAdvance, 'tab', 'input');
```
<p>The available synthetic events are listed in <a href="#modules">the table of
modules above</a>. Most are linked to pages further detailing the specific eevnts.</p>
<h4>Creating DOM events</h4>
<p>Create your own synthetic events with `Y.Event.define(type, config)`.</p>
```
Y.Event.define("tripleclick", {
// The setup logic executed when node.on('tripleclick', callback) is called
on: function (node, subscription, notifier) {
// supporting methods can be referenced from `this`
this._clear(subscription);
// To make detaching easy, a common pattern is to add the subscription
// for the supporting DOM event to the subscription object passed in.
// This is then referenced in the detach() method below.
subscription._handle = node.on('click', function (e) {
if (subscription._timer) {
subscription._timer.cancel();
}
if (++subscription._counter === 3) {
this._clear(subscription);
// The notifier triggers the subscriptions to be executed.
// Pass its fire() method the triggering DOM event facade
notifier.fire(e);
} else {
subscription._timer =
Y.later(300, this, this._clear, [subscription]);
}
});
},
// The logic executed when the 'tripleclick' subscription is `detach()`ed
detach: function (node, subscription, notifier) {
// Clean up supporting DOM subscriptions and other external hooks
// when the synthetic event subscription is detached.
subscription._handle.detach();
if (subscription._timer) {
subscription._timer.cancel();
}
},
// Additional methods can be added to support the lifecycle methods
_clear: function (subscription) {
subscription._counter = 0;
subscription._timer = null;
},
...
});
```
<p>After the synthetic event is defined, it is available for every Node and
NodeList to subscribe to.</p>
```
Y.one('#hellokitty').on('tripleclick', omgYayCantClickEnough);
```
<p>There is additional configuration to <a href="synths.html">add support for
`delegate()` or extra subscription arguments</a>, but often very little extra
code is needed.</p>
<h2>FAQ</h2>
<ul>
<li><a href="#">My callback is executing at the wrong time. What's going on?</a></li>
<li><a href="#">I'm getting an error in my callback that "(some object) has no method (someMethodOnMyObject)". What am I missing?</a></li>
<li><a href="#">What events can I subscribe to?</a></li>
<li><a href="#">Why isn't on() chainable?</a></li>
<li><a href="#">Why would I use `Y.on()` or `Y.delegate()` instead of `node.on()` and `node.delegate()`?</a></li>
<li><a href="#">EventTarget also provides an `after()` method. How does that work for DOM events?</a></li>
<li><a href="#">When I subscribe to an event from a NodeList, `this` is the NodeList, not the individual Node. What's up with that?</a></li>
<li><a href="#">Where is `nodelist.delegate()`?</a></li>
<li><a href="#">What works and what doesn't on mobile browsers?</a></li>
<li><a href="#faking">Why shouldn't I fake DOM events in user facing code?</a></li>
</ul>
<h2 id="event-whitelist">Appendix A: Whitelisted DOM events</h2>
<div id="events">
<table>
<thead>
<tr>
<th>Event</th>
<th>Added by</th>
</tr>
</thead>
<tbody>
<tr>
<td>abort</td>
<td>node-base</td>
</tr>
<tr>
<td>beforeunload</td>
<td>node-base</td>
</tr>
<tr>
<td>blur</td>
<td>node-base</td>
</tr>
<tr>
<td>change</td>
<td>node-base</td>
</tr>
<tr>
<td>click</td>
<td>node-base</td>
</tr>
<tr>
<td>close</td>
<td>node-base</td>
</tr>
<tr>
<td>command</td>
<td>node-base</td>
</tr>
<tr>
<td>contextmenu</td>
<td>node-base</td>
</tr>
<tr>
<td>dblclick</td>
<td>node-base</td>
</tr>
<tr>
<td>DOMMouseScroll</td>
<td>node-base</td>
</tr>
<tr>
<td>drag</td>
<td>node-base</td>
</tr>
<tr>
<td>dragstart</td>
<td>node-base</td>
</tr>
<tr>
<td>dragenter</td>
<td>node-base</td>
</tr>
<tr>
<td>dragover</td>
<td>node-base</td>
</tr>
<tr>
<td>dragleave</td>
<td>node-base</td>
</tr>
<tr>
<td>dragend</td>
<td>node-base</td>
</tr>
<tr>
<td>drop</td>
<td>node-base</td>
</tr>
<tr>
<td>error</td>
<td>node-base</td>
</tr>
<tr>
<td>focus</td>
<td>node-base</td>
</tr>
<tr>
<td>key</td>
<td>node-base</td>
</tr>
<tr>
<td>keydown</td>
<td>node-base</td>
</tr>
<tr>
<td>keypress</td>
<td>node-base</td>
</tr>
<tr>
<td>keyup</td>
<td>node-base</td>
</tr>
<tr>
<td>load</td>
<td>node-base</td>
</tr>
<tr>
<td>message</td>
<td>node-base</td>
</tr>
<tr>
<td>mousedown</td>
<td>node-base</td>
</tr>
<tr>
<td>mouseenter</td>
<td>node-base</td>
</tr>
<tr>
<td>mouseleave</td>
<td>node-base</td>
</tr>
<tr>
<td>mousemove</td>
<td>node-base</td>
</tr>
<tr>
<td>mousemultiwheel</td>
<td>node-base</td>
</tr>
<tr>
<td>mouseout</td>
<td>node-base</td>
</tr>
<tr>
<td>mouseover</td>
<td>node-base</td>
</tr>
<tr>
<td>mouseup</td>
<td>node-base</td>
</tr>
<tr>
<td>mousewheel</td>
<td>node-base</td>
</tr>
<tr>
<td>orientationchange</td>
<td>node-base</td>
</tr>
<tr>
<td>reset</td>
<td>node-base</td>
</tr>
<tr>
<td>resize</td>
<td>node-base</td>
</tr>
<tr>
<td>select</td>
<td>node-base</td>
</tr>
<tr>
<td>selectstart</td>
<td>node-base</td>
</tr>
<tr>
<td>submit</td>
<td>node-base</td>
</tr>
<tr>
<td>scroll</td>
<td>node-base</td>
</tr>
<tr>
<td>textInput</td>
<td>node-base</td>
</tr>
<tr>
<td>unload</td>
<td>node-base</td>
</tr>
<tr>
<td>DOMActivate</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>DOMContentLoaded</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>afterprint</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>beforeprint</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>canplay</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>canplaythrough</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>durationchange</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>emptied</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>ended</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>formchange</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>forminput</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>hashchange</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>input</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>invalid</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>loadedmetadata</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>loadeddata</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>loadstart</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>offline</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>online</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>pagehide</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>pageshow</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>pause</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>play</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>playing</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>popstate</td>
<td>node-event-html5 or history</td>
</tr>
<tr>
<td>progress</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>ratechange</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>readystatechange</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>redo</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>seeking</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>seeked</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>show</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>stalled</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>suspend</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>timeupdate</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>undo</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>volumechange</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>waiting</td>
<td>node-event-html5</td>
</tr>
<tr>
<td>touchstart</td>
<td>event-touch</td>
</tr>
<tr>
<td>touchmove</td>
<td>event-touch</td>
</tr>
<tr>
<td>touchend</td>
<td>event-touch</td>
</tr>
<tr>
<td>touchcancel</td>
<td>event-touch</td>
</tr>
<tr>
<td>gesturestart</td>
<td>event-touch</td>
</tr>
<tr>
<td>gesturechange</td>
<td>event-touch</td>
</tr>
<tr>
<td>gestureend</td>
<td>event-touch</td>
</tr>
<tr>
<td>transitionend or webkitTransitionEnd</td>
<td>transition-native</td>
</tr>
</tbody>
</table>
</div>
<script>
YUI({ filter: 'raw' }).use('selector-css3', 'datatable-sort', function (Y) {
var data = [],
node = Y.one('#events');
node.all('td:nth-of-type(1)').each(function (node, i) {
data.push({
Event: node.get('text'),
"Added By": node.next().get('text')
});
});
node.empty().addClass('yui3-skin-sam');
new Y.DataTable.Base({
columnset: [
{ key: 'Event', sortable: true },
{ key: 'Added By', sortable: true }
],
recordset: data
}).plug(Y.Plugin.DataTableSort).render(node);
});
</script>
<h4>Adding to the DOM event whitelist</h4>
<p>If you need to use an event that isn't included in this list, and not
supplied by a synthetic event, you can expand the whitelist by adding the event
names to the `Y.Node.DOM_EVENTS` object.</p>
```
// Allow for subscription to some mostly cross-browser mutation events
Y.mix(Y.Node.DOM_EVENTS, {
DOMNodeInserted: true,
DOMNodeRemoved: true,
DOMCharacterDataModified: true
});
```
<h2 id="facade-properties">Appendix B: EventFacade properties and methods</h2>
<h4>Methods</h4>
<dl>
<dt>`e.preventDefault()`</dt>
<dd>
Prevents the default action associated with the event. E.g. page
navigation from an &lt;a&gt;nchor `click` or form submission and
page reload from a %lt;form&gt; `submit`.
</dd>
<dt>`e.stopPropagation()`</dt>
<dd>
Stops the event from bubbling further up the DOM tree. This does
not prevent the default action if there is one. Subsequent event
subscribers will be executed.
</dd>
<dt>`e.stopImmediatePropagation()`</dt>
<dd>
Stops the event from bubbling further up the DOM tree. This does
not prevent the default action if there is one. Subsequent event
subscribers will NOT be executed.
</dd>
<dt>`e.halt( [immediate=false] )`</dt>
<dd>
Alias for `e.preventDefault(); e.stopPropagation();` or
`e.preventDefault(); e.stopImmediatePropagation();`, depending on
the <em>immediate</em> parameter.
</dd>
</dl>
<h4>Basics</h4>
<dl>
<dt>`e.type`</dt>
<dd>
The name of the event. E.g. "click", "keyup", or "load".
</dd>
<dt>`e.target`</dt>
<dd>
The Node instance that originated the event (see <a
href="#currenttarget">What's the difference between `e.target` and
`e.currentTarget`</a>)
</dd>
<dt>`e.currentTarget`</dt>
<dd>
The Node instance that subscribed to the event. In the case of
subscriptions from NodeLists, this is still the individual Node
instance (see <a href="#nodelistthis">When I subscribe to an event
from a NodeList, `this` is the NodeList...</a>).
</dd>
<dt>`e.relatedTarget`</dt>
<dd>
For `mouseover` events, this will be the Node instance of where the
mouse travelled <em>from</em>. For `mouseout`, it will be the Node
that the mouse travelled <em>to</em>.
</dd>
</dl>
<h4>Keyboard event properties</h4>
<dt>`e.keyCode`</dt>
<dd>
The unicode value of a non-character key in a `keypress` event or
any key in `keydown` or `keyup`. See <a
href="https://developer.mozilla.org/en/DOM/event.keyCode">event.keyCode
on MDC</a>.
</dd>
<dt>`e.charCode`</dt>
<dd>
The Unicode value of a character key pressed during a keypress
event. See <a
href="https://developer.mozilla.org/en/DOM/event.charCode">event.charCode
on MDC</a>.
</dd>
<dt>`e.shiftKey`</dt>
<dd>
`true` if the shift key was depressed during a key event.
</dd>
<dt>`e.ctrlKey`</dt>
<dd>
`true` if the control key was depressed during a key event.
</dd>
<dt>`e.altKey`</dt>
<dd>
`true` if the alt/option key was depressed during a key event.
</dd>
<dt>`e.metaKey`</dt>
<dd>
`true` if the "Windows" key on PCs or command key on Macs was
depressed during a key event.
</dd>
</dl>
<h4>Mouse event properties</h4>
<dt>`e.button`</dt>
<dd>
For `mouseup` events (<em>NOT `click` events</em>), indicates
which mouse button is pressed.<br>
`1` = left click, `2` = middle click, `3` = right click.
</dd>
<dt>`e.which`</dt>
<dd>
Alias for e.button.
</dd>
<dt>`e.pageX`</dt>
<dd>
The horizontal coordinate of the event relative to whole document.
</dd>
<dt>`e.pageY`</dt>
<dd>
The vertical coordinate of the event relative to whole document.
</dd>
<dt>`e.clientX`</dt>
<dd>
The horizontal coordinate of the event relative to viewport,
regardless of scrolling.
</dd>
<dt>`e.clientY`</dt>
<dd>
The vertical coordinate of the event relative to viewport,
regardless of scrolling.
</dd>
<dt>[`e.wheelDelta`]</dt>
<dd>
For `mousewheel` or `DOMMouseScroll` events, the pixel distance of
the scroll.
</dd>
</dl>
<h4>Touch/Mobile related properties</h4>
<dl>
<dt>[`e.touches`]</dt>
<dd>
</dd>
<dt>[`e.targetTouches`]</dt>
<dd>
</dd>
<dt>[`e.changedTouches`]</dt>
<dd>
</dd>
<dt>[`e.scale`]</dt>
<dd>
</dd>
<dt>[`e.rotation`]</dt>
<dd>
</dd>
<dt>[`e.identifier`]</dt>
<dd>
</dd>
</dl>
<p>Synthetic events may add or modify event facade properties. These should be included in the documentation for the specific synthetic event.</p>
<p>For more details, check out the <a
href="https://developer.mozilla.org/en/DOM/event#Properties">MDC
documentation</a>.</p>