index.mustache revision 5d3dc0444c51f18e44c016a89b16a8951529518c
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<style>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync h4 code {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync text-transform: none;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync }
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</style>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<div class="intro component">
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>The YUI Event Utility provides APIs for working with the browser's DOM
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync event system. It simplifies tasks like subscribing to button `click`s or
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync canceling &lt;form&gt; `submit`s to, for example, allow sending data to the
92a27575521748a392dcd1b996fce55b87411a00vboxsync server via ajax.</p>
92a27575521748a392dcd1b996fce55b87411a00vboxsync
92a27575521748a392dcd1b996fce55b87411a00vboxsync <p>In addition, the "Synthetic event" system supplies <em>entirely new</em>
92a27575521748a392dcd1b996fce55b87411a00vboxsync DOM events to subscribe to as well as fixing events that behave differently
92a27575521748a392dcd1b996fce55b87411a00vboxsync across browsers. Implementers can create their own DOM events triggered by
92a27575521748a392dcd1b996fce55b87411a00vboxsync specific user actions or other environmental criteria.</p>
92a27575521748a392dcd1b996fce55b87411a00vboxsync
92a27575521748a392dcd1b996fce55b87411a00vboxsync <p>The API for working with DOM events is provided by the EventTarget class,
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync which also services the Custom event infrastructure that is used throughout
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync YUI. Read more about working with custom events <a
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync href="../event-custom/index.html">in the EventTarget user guide</a>.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</div>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync{{>getting-started}}
10cdf5733351fdcd857d439ca32189e812f18682vboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync<h2>The Basics</h2>
10cdf5733351fdcd857d439ca32189e812f18682vboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync<h4>Listening for events</h4>
10cdf5733351fdcd857d439ca32189e812f18682vboxsync```
10cdf5733351fdcd857d439ca32189e812f18682vboxsync// Step 1. Capture a button node
10cdf5733351fdcd857d439ca32189e812f18682vboxsyncvar button = Y.one("#readygo");
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync// Step 2. Subscribe to its click event with a callback function
10cdf5733351fdcd857d439ca32189e812f18682vboxsyncbutton.on("click", function (e) {
10cdf5733351fdcd857d439ca32189e812f18682vboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync // Step 3. do stuff when the button is clicked
10cdf5733351fdcd857d439ca32189e812f18682vboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync});
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
cd9e4940318086a06a68bf301960563dcb72b939vboxsync<p><code>on(<em>type</em>, <em>callback</em>)</code> is the main
cd9e4940318086a06a68bf301960563dcb72b939vboxsyncsubscription method, and is available on every <a href="../node/">`Node`</a>
cd9e4940318086a06a68bf301960563dcb72b939vboxsyncand <a href="../node/#nodelist">`NodeList`</a>.</p>
10cdf5733351fdcd857d439ca32189e812f18682vboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>Replace "click" with <a href="#event-whitelist">any other event name</a> to subscribe to that event.</p>
10cdf5733351fdcd857d439ca32189e812f18682vboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync<h4>The Callback and the Event Object</h4>
10cdf5733351fdcd857d439ca32189e812f18682vboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
10cdf5733351fdcd857d439ca32189e812f18682vboxsyncbutton.on('click', function (e) {
10cdf5733351fdcd857d439ca32189e812f18682vboxsync // `this` is the button Node, NOT the DOM element
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync this.get('id'); // ==> 'readygo' (from <button id="readygo">...</button>)
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync // Event properties that point to the DOM are also Node instances
10cdf5733351fdcd857d439ca32189e812f18682vboxsync e.target.get('id'); // => 'readygo'
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync // Stop the event's default behavior
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync e.preventDefault();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync // Stop the event from bubbling up the DOM tree
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync e.stopPropagation();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync});
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
cd9e4940318086a06a68bf301960563dcb72b939vboxsync<p>Subscribed callbacks are passed a <a href="#facade-properties">a normalized
10cdf5733351fdcd857d439ca32189e812f18682vboxsyncevent object</a> as their first argument.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
10cdf5733351fdcd857d439ca32189e812f18682vboxsync<p>The keyword "`this`" in the callback will refer to the Node or NodeList
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncthat you subscribed from.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<h4>`e.preventDefault()` and `e.stopPropagation()`</h4>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>Many events have a default behavior, such as the `submit` event serializing
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncform data and making a new page request. Disable this behavior with
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync`e.preventDefault()`.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
86abc60770f825f8c2ed4257675b50a08743b687vboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncfunction setFilter(e) {
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync // Stop the link from loading the href page
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync e.preventDefault();
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync // Now do my own thing instead
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync var url = this.get('href').replace(/page/, 'partial');
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync Y.one('#contentArea').load(url);
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync // `return false` is supported, but not preferred. use e.preventDefault()
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync return false;
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync}
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsyncY.one('#table-filter-link').on('click', setFilter);
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync```
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync
4a429a59b1a82ce092626ea5f7512466c18f2015vboxsync<p>Most events can be listened for on the specific element that originates them
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<em>or from any of their parent elements</em>, all the way up to the
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync`document`. Prevent dispatching the event to subscriptions bound to elements
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncfurther up the DOM tree with `e.stopPropagation()`. In practice, this is
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncrarely useful.</p>
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync<p>Returning `false` from a callback will also stop the propagation of the
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncevent, which may cause unintended side effects.</p>
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>`e.stopPropagation()` won't prevent the execution of other subscribers
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsynclistening to the same element, only elements further up the DOM tree. If you
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncneed to stop all execution, use `e.stopImmediatePropagation()` or
86abc60770f825f8c2ed4257675b50a08743b687vboxsync`e.halt(true)`. The latter will also call `e.preventDefault()`.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<h4>Detaching subscriptions</h4>
86abc60770f825f8c2ed4257675b50a08743b687vboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>`node.on()` and all
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync<a href="#more">other subscription methods</a> return a
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncsubscription object that can be used to unbind that subscription. Node also
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncsupports a `detach()` method and <a href="#detach-methods">other ways to cleaup
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncsubscriptions</a>.</p>
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync```
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync// on() returns a subscription handle...
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncvar sub = button.on("click", handleClick);
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync// ...that can be used to unbind the subscription
02fb80eb0db13569db21d1ce5e0f3e0d5a6122aavboxsyncsub.detach();
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync// Alternately, use the Node's detach() method
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncbutton.detach("click", handleClick);
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync```
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync<p>Just this should take care of most of the simple event bindings you'll need.
23ee8310386e73ba6760fa30831a7964713d34b6vboxsyncThere's <a href="#more">a lot more you can do</a>, though, so read on!</p>
6967517de4be849f55b0141d6089add0eff2aa7bvboxsync
6967517de4be849f55b0141d6089add0eff2aa7bvboxsync<h2 id="modules">What to `use()`</h2>
23ee8310386e73ba6760fa30831a7964713d34b6vboxsync
86abc60770f825f8c2ed4257675b50a08743b687vboxsync<p>
7b213bb002950f9fcf809f605cc584fa543481advboxsync Before we get into <a href="#more">more API goodies</a>, let's talk about
7b213bb002950f9fcf809f605cc584fa543481advboxsync the Event Utility's module breakdown.
7b213bb002950f9fcf809f605cc584fa543481advboxsync</p>
7b213bb002950f9fcf809f605cc584fa543481advboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync For starters, in most cases <em>you probably won't `use('event')`</em>.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync The core DOM event system ("event-base") is required by the "node-base"
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync module, which itself if required by just about everything in YUI. So you
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync probably already have the DOM event API and didn't know it!
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>Here is the full breakdown of modules in the DOM event system:</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<table>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<thead>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
cd9e4940318086a06a68bf301960563dcb72b939vboxsync <th>`use("______", ...)`</th>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <th>What's in it?</th>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</thead>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<tbody>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-base.html">`event-base`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync <p>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync The core DOM event subscription system as well as the DOM
cd9e4940318086a06a68bf301960563dcb72b939vboxsync lifecycle events <a href="domready.html">`domready`,
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync `contentready`, and `available`</a>. Notably, it does NOT
cd9e4940318086a06a68bf301960563dcb72b939vboxsync include
8364ffb7e421fa1ec2bd282ab4c52ac718873d46vboxsync </p>
8364ffb7e421fa1ec2bd282ab4c52ac718873d46vboxsync <ul>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>event delegation</li>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>event simulation</li>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>synthetic events</li>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </ul>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>If you've `use()`d anything, you probably have this already.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event.html">`event`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync A rollup of all modules below except
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <ul>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>"event-simulate"</li>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>"node-event-simulate"</li>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>"node-event-delegate" (which is in the "node" rollup)</li>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </ul>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-delegate.html">`event-delegate`</a> &amp;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <br>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <a style="white-space: nowrap;" href="{{apiDocs}}/module_node-event-delegate.html">`node-event-delegate`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Adds the `Y.delegate(...)` and `node.delegate(...)` methods,
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync respectively, for <a href="#delegation">event delegation</a>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync convenience.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-simulate.html">`event-simulate`</a> &amp;
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <br>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <a style="white-space: nowrap;" href="{{apiDocs}}/module_node-event-simulate.html">`node-event-simulate`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Adds `Y.Event.simulate(...)` and `node.simulate(...)` for
08a80484275b5172ce23729ecccc934c6a92d201vboxsync <a href="#simulate">triggering native DOM events</a> for
08a80484275b5172ce23729ecccc934c6a92d201vboxsync unit testing.
08a80484275b5172ce23729ecccc934c6a92d201vboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
86abc60770f825f8c2ed4257675b50a08743b687vboxsync <strong>Note: <a href="simulate.html#faking">Faking DOM events
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync should not be used in user facing code</a></strong>.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-synthetic.html">`event-synthetic`</a></td>
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync <td>
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync <p>Supplies the infrastructure for creating new DOM events, "fixing"
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync existing events with undesirable or inconsistent behavior, and
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync <a href="synths.html">all sorts of other things</a>.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <p>All of the modules below are synthetics.</p>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </tr>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <tr>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td><a href="{{apiDocs}}/module_event-flick.html">`event-flick`</a></td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync Adds a <a href="touch.html#flick">"flick" event</a> for touch or
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync mouse interaction.
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </tr>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <tr>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td><a href="{{apiDocs}}/module_event-focus.html">`event-focus`</a></td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <a href="focus.html">Fixes `focus` and `blur` events</a> to bubble
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync (for delegation).
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </tr>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td><a href="{{apiDocs}}/module_event-gestures.html">`event-gestures`</a></td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <p>A rollup of the following modules:</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <ul>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>"event-touch"</li>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <li>"event-move"</li>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <li>"event-flick"</li>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </ul>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
bc8beda7587b16cafe7de7bea19149de1bd4b498vboxsync <p>In the future, may contain more gesture abstraction modules.</p>
bc8beda7587b16cafe7de7bea19149de1bd4b498vboxsync </td>
3acaac88e9a4c925226db26f0d374f9f4876b74fvboxsync <tr>
cc8517c11be66037a9873fa03f280e7742efed6dvboxsync <td><a href="{{apiDocs}}/module_event-hover.html">`event-hover`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Adds a <a href="mouseenter.html#hover">"hover" event</a> which
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync binds to two callbacks, one for the start, and one for the end of a
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync mouse hover.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-key.html">`event-key`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Adds a <a href="key.html">"key" event</a> which listens for
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync specific, implementer defined, keys being pressed by the user.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-mouseenter.html">`event-mouseenter`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Adds <a href="mouseenter.html">"mouseenter" and "mouseleave"
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync events</a>. You probably want to use these instead of "mouseover"
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync and "mouseout".
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-mousewheel.html">`event-mousewheel`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <p>Adds a "mousewheel" event for monitoring users scrolling the
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync window with the mousewheel. Event facades passed to the callback
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync will have an `e.wheelDelta` property corresponding to the amount of
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync scrolling.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>Currently, this event can only be subscribed with
08a56d5836eceeb24642b61eaa52a4edb0a7b482vboxsync `Y.on("mousewheel", callback)`;</p>
08a56d5836eceeb24642b61eaa52a4edb0a7b482vboxsync </td>
08a56d5836eceeb24642b61eaa52a4edb0a7b482vboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync <td><a href="{{apiDocs}}/module_event-move.html">`event-move`</a></td>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Adds <a href="touch.html#move">"gesturemovestart", "gesturemove",
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync and "gesturemoveend" events</a> that serve as abstractions over
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync mouse and touch events, forking internally based on the client
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync device.
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <tr>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync <td><a href="{{apiDocs}}/module_event-outside.html">`event-outside`</a></td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
16aeb8f83239d4a4a10ecac1fb46fe24a8bdbb66vboxsync Adds a <a href="outside.html">"clickoutside" and several other
16aeb8f83239d4a4a10ecac1fb46fe24a8bdbb66vboxsync outside events</a> to trigger behavior based on actions taken
16aeb8f83239d4a4a10ecac1fb46fe24a8bdbb66vboxsync outside a specific element.
16aeb8f83239d4a4a10ecac1fb46fe24a8bdbb66vboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td><a href="{{apiDocs}}/module_event-resize.html">`event-resize`</a></td>
2705a216ac12110a0813d671e230797c886b4788vboxsync <td>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync <p>Adds a "windowresize" event that only fires after a user has
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync stopped dragging a window's resize handle. This normalizes the
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync `window.onresize` event across browsers.</p>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync <p>This event can only be subscribed with
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync `Y.on("windowresize", callback)`;</p>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync </td>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync </tr>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync <tr>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync <td><a href="{{apiDocs}}/module_event-touch.html">`event-touch`</a></td>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync <td>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync Adds support for <a href="touch.html">subscribing to native touch
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync and gesture events</a>.
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync </td>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync </tr>
24b88f881835a6c392e72177f74f1d5e4544ba1evboxsync <tr>
f8244da4b4e02d8d4ce0669eeb4093e31c301888vboxsync <td><a href="{{apiDocs}}/module_event-valuechange.html">`event-valuechange`</a></td>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync <td>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync Adds a <a href="valuechange.html">"valueChange" event</a> that fires when input element text
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync changes (this is harder than you think).
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync </td>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync </tr>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync</tbody>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync</table>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync<h2 id="delegation">Event Delegation</h2>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync<p>If you don't already know what event delegation is, you should <a
1cc3bd5463294790ba54c78fde5313264185e50cvboxsynchref="delegation.html">read this quick overview</a>. Short form: <em>you need
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncto be using this</em>.</p>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync```
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync// single element subscription
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsyncnode.on("click", handleClick);
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync// delegated subscription for all button clicks from inside the node
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncnode.delegate("click", handleClick, "button, input[type=button]");
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync```
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync<p>Creating a delegated subscription looks very much like creating any other
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncevent subscription with two differences. First, it's a different method name,
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync`delegate`. Second, there is another argument: a CSS selector that is used to
1cc3bd5463294790ba54c78fde5313264185e50cvboxsynctest the event's originating element to decide if the callback should be
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncexecuted. If the event started at or inside an element matching the selector,
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncthe callback will execute.</p>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
bee07f28c146fb5313ea13d84dcd508d8f604a10vboxsync<p>Unlike `node.on()` subscriptions, the `this` object in `node.delegate()`
441e51789084e8795573747fec9f5108e8b54e98vboxsynccallbacks will refer to the element that matched the css filter, not to `node`.
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncWe did this because likely your logic revolves around the nodes described by
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsyncthe filter, not around the element that contains them.</p>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync```
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsyncfunction handleClick (e) {
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync // `this` is the button with class .remove, not the #items element
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync // remove the containing LI
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync this.ancestor('li').remove();
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync // e.currentTarget is also the button.remove
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync // e.container === Y.one('#items')
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync}
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncY.one('#items').delegate('click', handleClick, 'button.remove');
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync```
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync<p>For more complex target filtering, a function can be passed instead of a css
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsyncselector. See the
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync<a href="{{apiDocs}}/module_event-delegate.html#method_delegate">API docs</a>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsyncfor more details.</p>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync<p>As noted <a href="#modules">above</a>, the `event-delegate` module is
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsyncincluded in the `event` rollup, but `node-event-delegate` isn't. We recommend
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsyncusing delegation from the Node API, so you should `use()` either
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync`node-event-delegate` or the `node` rollup.</p>
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync<h2 id="more">More Event API Goodness</h2>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync<p>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync Here is a sampling of some of the other ways to manage event subscriptions
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync in YUI.
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync</p>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync<h4 id="y-on">Subscribe from `Y`</h4>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync```
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync// Y.on() takes a third argument which is the Node, DOM element,
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync// or CSS selector of the element(s) to bind
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncY.on("click", handleClick, "#readygo");
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync// Y.delegate() similarly takes the containing element or selector
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync// as the third argument
1cc3bd5463294790ba54c78fde5313264185e50cvboxsyncY.delegate("click", handleClick, "#container", "button, input[type=button]");
8d466f9285d86e81f927c2bf053a2eb7ec325746vboxsync```
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync<p>
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync An alternate syntax for DOM subscriptions is using `Y.on()` or
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync `Y.delegate()`. When identifying the target by a CSS selector, these
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync methods can be used regardless if the element is currently available for
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync scripting. If it's not yet on the page, a poll will regularly look for it
1cc3bd5463294790ba54c78fde5313264185e50cvboxsync (for a few seconds) and the subscription will be automatically attached
efda5c4c4db213abd0692df0ea34a26f6230d59avboxsync when the element is found. Relying on this behavior can introduce race
2705a216ac12110a0813d671e230797c886b4788vboxsync conditions, though, so use it wisely.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Use of `Y.on()` instead of `node.on()` is largely a stylistic preference,
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync though <a href="#y-on-vs-node-on">there are some technical differences</a>.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<h4 id="once">One time subscriptions</h4>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
42d36464aee6c81b4f206b6c02035587501ff67cvboxsynctabLabel.once('mouseover', loadTabContent);
c3e38cccf650831700227918a021e6c4097ace82vboxsync```
42d36464aee6c81b4f206b6c02035587501ff67cvboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<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 automatically be detached after the event fires.</p>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync<p>The signature for `once()` is the same as `on()`.</p>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<h4>Grouping subscriptions</h4>
3b3bc8a9383a065307e540b83fc3a3d6c548a082vboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync<p>Pass an object to subscribe to multiple events, each with their own
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsynccallback</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync```
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsyncfunction validate(e) { ... }
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncfunction clearPlaceholder(e) { ... }
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncvar groupSub = inputNode.on({
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync blur : validate,
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync keypress: validate,
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync focus : clearPlaceholder
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync});
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// Detach the blur, keypress, and focus subscriptions in one call
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncgroupSub.detach();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync<p>Pass an array to subscribe to multiple events with the same callback</p>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync```
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsyncfunction activate(e) { ... }
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsyncgroupSub = inputNode.on(['focus', 'mouseover'], activate);
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync// Detach the focus and mouseover subscriptions
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsyncgroupSub.detach();
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync```
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync<p>Prefix the event name with a category to allow detaching multiple
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsyncsubscriptions by that category.</p>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync```
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsyncinputNode.on('my-category|focus', activate);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncinputNode.on('my-category|mouseover', activate);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// You can detach specific subscriptions by 'my-category|focus' or all with |*
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncinputNode.detach('my-category|*');
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
cd9e4940318086a06a68bf301960563dcb72b939vboxsync<p>The `once()` and `delegate()` methods also support these alternate
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncsignatures.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
5857f4e58ce2ef50d7f0c450fe4897026f9a9c3dvboxsync<h4 id="extended-signature">Binding `this` and additional callback arguments</h4>
42dc09ee69e746b8641cfa190931a15ecfd7295cvboxsync
e0b91e4f93fb43371374df4aeb636dffea336056vboxsync<p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync By default, the "`this`" object in subscription callbacks will be the Node
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync or NodeList that subscribed to them. Override this default by passing your
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync own `this` object as the third argument to `on()` or the fourth to
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync `delegate()`. Note that the argument index is shifted when using `Y.on()`
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync and `Y.delegate()` or <a href="synths.html">synthetic events with custom
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync signatures</a>.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// equivalent to node.on('click', function (e) { overlay.hide(e); });
2705a216ac12110a0813d671e230797c886b4788vboxsyncnode.on('click', overlay.show, overlay);
2705a216ac12110a0813d671e230797c886b4788vboxsync
2705a216ac12110a0813d671e230797c886b4788vboxsyncnode.once('mouseover', door.unlock, door);
bcc95fabf162c0f743d7eaafb0d21f7ef967e9f4vboxsync
2705a216ac12110a0813d671e230797c886b4788vboxsync// `this` override comes after the filter; also shifted for the 'key' event's
2705a216ac12110a0813d671e230797c886b4788vboxsync// custome signature.
2705a216ac12110a0813d671e230797c886b4788vboxsynccontainer.delegate('key', validator.isValid, 'enter,tab', 'input', validator);
2705a216ac12110a0813d671e230797c886b4788vboxsync
2705a216ac12110a0813d671e230797c886b4788vboxsync// Corresponding alternatives from Y
2705a216ac12110a0813d671e230797c886b4788vboxsyncY.on('click', overlay.show, '#show', overlay);
2705a216ac12110a0813d671e230797c886b4788vboxsync
2705a216ac12110a0813d671e230797c886b4788vboxsyncY.once('mouseover', door.unlock, '#gate13', door);
de86a09bf42f7e7d80a0a5acf1e8e99d445be1d3vboxsync
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsyncY.delegate('key', validator.isValid, '#myForm', 'enter,tab', 'input', validator);
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsync```
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsync
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsync<p>Additional arguments passed to the subscription methods will be sent along
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsyncto the callback after the event facade. If you want to bind extra arguments,
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsyncbut don't want to override the "`this`" object, pass `null` for the `this`
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsyncargument.</p>
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync
2705a216ac12110a0813d671e230797c886b4788vboxsync```
2705a216ac12110a0813d671e230797c886b4788vboxsyncMyClass.prototype = {
2705a216ac12110a0813d671e230797c886b4788vboxsync someMethod: function (param) {
2705a216ac12110a0813d671e230797c886b4788vboxsync Y.log(param); // => "I'm Extra!"
2705a216ac12110a0813d671e230797c886b4788vboxsync },
2705a216ac12110a0813d671e230797c886b4788vboxsync
95d42763b8808d795c23148d7dbc00a3b7b40d6fvboxsync handleClick: function (e, extraParam) {
2705a216ac12110a0813d671e230797c886b4788vboxsync this.someMethod(extraParam);
2705a216ac12110a0813d671e230797c886b4788vboxsync ...
2705a216ac12110a0813d671e230797c886b4788vboxsync },
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ...
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync};
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncvar instance = new Y.MyClass();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync// The extra arg is passed as the second param to the callback after `e`
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncY.one('#readygo').on('click', instance.handleClick, instance, "I'm Extra!");
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<h4 id="detach-methods">More ways to clean up subscriptions</h4>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
5c571d69a0355bedb9a401ce4de992a2b0ef3515vboxsync<p>There are a lot of options for detaching events in YUI. See the table below for details.</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<table>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<thead>
c0da96af18c7b40ac5cfd7e7ea398a398540f224vboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <th>Method</th>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <th>What it does</th>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</thead>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<tbody>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
17aee8484f9e8699c2515d450552c622aea0889evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync var subscription = node.on('click', callback);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync subscription.detach();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
17aee8484f9e8699c2515d450552c622aea0889evboxsync </td>
17aee8484f9e8699c2515d450552c622aea0889evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Removes a specific subscription or, if created with one of the
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync group subscription methods, a group of subscriptions.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
17aee8484f9e8699c2515d450552c622aea0889evboxsync <p>
17aee8484f9e8699c2515d450552c622aea0889evboxsync Generally, this is the best method to use.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr id="remove-by-category">
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
17aee8484f9e8699c2515d450552c622aea0889evboxsync node.on('foo-category|click', callback);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.detach('foo-category|click');
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync // OR
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.detach('foo-category|*');
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
17aee8484f9e8699c2515d450552c622aea0889evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
41beaec6d563ed06201d5e42a0e8cf32c06b3388vboxsync <p>
0c657f93ac727a3a1644497331d86fbcbc3722aavboxsync Removes a subscription or group of subscriptions that included
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync the specified category in the subscription event type.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
42dc09ee69e746b8641cfa190931a15ecfd7295cvboxsync <p>
42dc09ee69e746b8641cfa190931a15ecfd7295cvboxsync This is typically only safe in implementation code, not
42dc09ee69e746b8641cfa190931a15ecfd7295cvboxsync module code, because multiple subscriptions using the same type
ee6495ebe54829fea21ffbb6f1275315e72d4506vboxsync and category will be detached by the call to `detach`.
42dc09ee69e746b8641cfa190931a15ecfd7295cvboxsync </p>
98bfcb808aa93fe8b532eb38da1f15a795a85f6dvboxsync </td>
98bfcb808aa93fe8b532eb38da1f15a795a85f6dvboxsync </tr>
42dc09ee69e746b8641cfa190931a15ecfd7295cvboxsync <tr>
42dc09ee69e746b8641cfa190931a15ecfd7295cvboxsync <td>
aebbe380e89aef2b57dbf7a30f70536c5d807b74vboxsync ```
e0b91e4f93fb43371374df4aeb636dffea336056vboxsync node.detach('click', callback);
17aee8484f9e8699c2515d450552c622aea0889evboxsync // OR
e0b91e4f93fb43371374df4aeb636dffea336056vboxsync node.detach('click');
e0b91e4f93fb43371374df4aeb636dffea336056vboxsync // OR
e0b91e4f93fb43371374df4aeb636dffea336056vboxsync node.detach():
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync If you have a reference to the subscribed callback function,
17aee8484f9e8699c2515d450552c622aea0889evboxsync (but not a subscription handle) use the two argument signature.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync With one argument, `detach` will remove all subscriptions for
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync the specified event. With no arguments, it removes all
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync subscriptions for all events.
17aee8484f9e8699c2515d450552c622aea0889evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync `detach` does not remove subscriptions from descendant nodes.
17aee8484f9e8699c2515d450552c622aea0889evboxsync </p>
17aee8484f9e8699c2515d450552c622aea0889evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
17aee8484f9e8699c2515d450552c622aea0889evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.detachAll();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
17aee8484f9e8699c2515d450552c622aea0889evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Works the same as `node.detach()`.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
cd9e4940318086a06a68bf301960563dcb72b939vboxsync </td>
cd9e4940318086a06a68bf301960563dcb72b939vboxsync </tr>
cd9e4940318086a06a68bf301960563dcb72b939vboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.purge();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync // OR
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.purge(true);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync // OR
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.purge(true, 'click');
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync With no arguments, `purge` works the same as `node.detach()`.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Passing `true` as a first argument will remove all
17aee8484f9e8699c2515d450552c622aea0889evboxsync subscriptions for all events from the node <em>and its
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync descendant subtree</em>. Passing an event type as a second
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync argument will only deep purge subscriptions to that event.
cd9e4940318086a06a68bf301960563dcb72b939vboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.empty();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Removes subscriptions for all events <em>only from the
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync descendants of a node</em> after removing them from the DOM.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.destroy();
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync // OR
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync node.destroy(true);
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync With no arguments, works like `node.detach()`.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync With `true` as a first argument, it works like
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync `node.purge(true)`.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync The `destroy` method does more than detaching event
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync subscribers. Read the
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <a href="{{apiDocs}}/classes/Node.html#method_destroy">API
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync docs</a> for details.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Y.Event.detach('click', callback, '#foo');
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Same as `Y.one('#foo').detach( [other args] )`.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
9300c669f18e40bb3bd8bb6a0f7efaeb2bbd790fvboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
9300c669f18e40bb3bd8bb6a0f7efaeb2bbd790fvboxsync <tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Y.Event.purgeElement('#foo', true, 'click');
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync <p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync Same as `Y.one('#foo').purge( [other args] )`.
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </td>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync </tr>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</tbody>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync</table>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<h2 id="simulate">Simulate browser events</h2>
17aee8484f9e8699c2515d450552c622aea0889evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync<p>
98bfcb808aa93fe8b532eb38da1f15a795a85f6dvboxsync For creating automated functional tests, being able to simulate user
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync interaction can be crucial. That's where the `node-event-simulate` module
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync comes in.
17aee8484f9e8699c2515d450552c622aea0889evboxsync</p>
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
98bfcb808aa93fe8b532eb38da1f15a795a85f6dvboxsync```
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncYUI().use('test', 'node-event-simulate', 'fancy', function (Y) {
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsyncvar test = new Y.Test.Case({
db3dbd0ed7eb69f804a8921fa23a1267ea01f46evboxsync ...
"clicking close button should dismiss UI": function () {
var widget = new Y.MyFancyWidget().render('#here'),
uiBox = widget.get('boundingBox'),
closeButton = uiBox.one('.close-button');
closeButton.simulate('click');
Y.Assert.isFalse( uiBox.inDoc() );
},
...
```
<p>
`node.simulate( type, eventProperties )` creates a native DOM event that
will bubble (if appropriate), but will not trigger native default behavior.
For example, `node.simulate('submit')` will not send data to the server for
a page reload.
</p>
<p>Read <a href="simulate.html">more about event simulation here</a>.</p>
<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 synthetic events that are available as core YUI modules are listed in
<a href="#modules">the table of modules above</a>, though there are others
<a href="http://yuilibrary.com/gallery/">in the Gallery</a>. Most events
listed in the table are linked to pages that describe the specific event in
more detail.
</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>Troubleshooting/FAQ</h2>
<ul>
<li><a href="#function-reference">My callback is executing at the wrong time. What's going on?</a></li>
<li><a href="#wrong-this">I'm getting an error in my callback that "(some object) has no method (someMethodOnMyObject)". What am I missing?</a></li>
<li><a href="#which-events">What events can I subscribe to?</a></li>
<li><a href="#why-on-no-chain">Why isn't on() chainable?</a></li>
<li><a href="#y-on-vs-node-on">Why would I use `Y.on()` or `Y.delegate()` instead of `node.on()` and `node.delegate()`?</a></li>
<li><a href="#after">EventTarget also provides an `after()` method. How does that work for DOM events?</a></li>
<li><a href="#nodelist-this">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="#nodelist-delegate">Where is `nodelist.delegate()`?</a></li>
<!--li><a href="#">What works and what doesn't on mobile browsers?</a></li-->
</ul>
<h4 id="function-reference">My callback is executing at the wrong time. What's going on?</h4>
<p>It's likely that you've included parenthese in the subscription.</p>
```
// WRONG
node.on('click', someFunction());
node.on('click', myObject.someFunction());
// RIGHT
node.on('click', someFunction);
node.on('click', myObject.someFunction, myObject);
```
<p>
Including the parens makes the function execute immediately, and pass the
return value from the function to `node.on('click', [RETURN VALUE])`. To
pass a function around, just omit the parens.
</p>
<h4 id="wrong-this">I'm getting an error in my callback that "`(some object) has no method (someMethodOnMyObject)`". What am I missing?</h4>
<p>
You may be passing an object method to `on()`, but forgot to include
<a href="#extended-signature">the `this` object override parameter</a> in
the subscription.
</p>
<p>
Another option to make sure object methods are called with the correct
`this` object is to use
<a href="{{apiDocs}}/classes/YUI.html#method_bind">`Y.bind(obj.method,
obj)`</a> or
<a href="{{apiDocs}}/classes/YUI.html#method_rbind">`Y.rbind(obj.method,
obj)`</a>.
</p>
```
// WRONG
node.on('click', myObj.method);
// RIGHT
node.on('click', myObj.method, myObj);
// RIGHT (alternate)
node.on('click', Y.rbind(obj.method, obj));
```
<h4 id="which-events">What events can I subscribe to?</h4>
<p>
It depends what modules you've included. Check out the
<a href="#event-whitelist">whitelisted events table</a>.
</p>
<h4 id="why-on-no-chain">Why isn't on() chainable?</h4>
<p>
After much deliberation, the YUI team decided that returning a subscription
handle was preferable to chaining in order to better support clean event
detaching across the various scenarios that DOM and custom events are used.
</p>
<p>
In any sizable application, managing event subscriptions becomes
increasingly important, and detaching events must be done with precision.
Because YUI allows duplicate subscriptions, any host-based detach method
will necessarily be less than 100% reliable with respect to avoiding
removal of subscriptions made by other parts of the system.
</p>
<p>
Otherwise, it's common to subscribe to events with anonymous functions,
which makes it impossible to detach the specific subscription by signature
because you don't have a function reference to use to identify the specific
subscription to remove. Subscription categories can be used, but
<a href="#remove-by-category">are also less precise</a> than
dealing with a specific subscription object.
</p>
<h4 id="y-on-vs-node-on">Why would I use `Y.on()` or `Y.delegate()` instead of `node.on()` and `node.delegate()`?</h4>
<p>
It's <a href="#y-on">largely a stylistic preference</a>, but there are some
technical differences when passing a selector string as a the third
argument to `Y.on()` or `Y.delegate()` (ala
`Y.on('click', callback, '#some select.or-string')`.
</p>
<ol>
<li>
<p>
`Y.on()` uses the
<a href="{{apiDocs}}/classes/Selector.html">Selector engine</a>
directly rather than calling through `Y.all(...)`.
</p>
<p>
The benefit here is that the Node and NodeList constructors add the
slightest bit of overhead to the subscription process.
</p>
</li>
<li>
When passing a selector that matches multiple elements, the `this` in
the callback will be the individual Node, not a
<a href="#nodelist-this">NodeList wrapping all matched elements</a>.
</li>
<li>
<p>
If called before the elements matching the selector are attached to
the DOM, it will poll for a few seconds and automatically attach
the subscription when the first matching element is found.
</p>
<p>
Note, if using a selector that matches multiple elements, the poll
will attach the subscription the first time Selector finds a match.
This <em>may not include all the elements</em> because either the
DOM is not fully updated yet, or the code that adds the matching
elements may happen in batches.
</p>
<p>In practice, it is best to avoid reliance on this behavior.</p>
</li>
</ol>
<h4 id="after">`EventTarget` also provides an `after()` method. How does that work for DOM events?</h4>
<p>
`node.after(...)` is equivalent to `node.on(...)`. The DOM doesn't expose
an "after" moment to hook into.
</p>
<h4 id="nodelist-this">When I subscribe to an event from a NodeList, `this` is the NodeList, not the individual Node. What's up with that?</h4>
<p>
In the callback, `e.currentTarget` will always refer to the individual Node.
However, if you call
</p>
```
Y.all('#some select.or-string').on('click', function (e) {
// how do I reference the NodeList?
});
```
<p>
you can't reference the NodeList captured by `Y.all()` without calling
`Y.all()` again, but that results in unnecessary overhead, and may match
different elements in the subsequent call.
</p>
<p>
In general, you should avoid `nodelist.on()` anyway,
<a href="#delegation">in favor of event delegation</a>.
</p>
<h4 id="nodelist-delegate">Where is `nodelist.delegate()`?</h4>
<p>
The point of delegation is to reduce the number of subscriptions being made.
`nodelist.delegate()` would be philosophically at odds with that. Either
call `node.delegate()` from an element higher up the DOM tree, or <em>if
you must</em> delegate the same event and callback from multiple
containers, use
</p>
```
nodelist.each(function (node) {
node.delegate('click', callback, '.not-recommended');
});
```
<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="delegation.html">the description of event delegation</a> for
reference)
</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="#nodelist-this">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>