YUI 3: Node

The Node Utility provides an expressive way to collect, create, and manipulate DOM nodes. Each Node instance represents an underlying DOM node, and each NodeList represents a collection of DOM nodes. With Node, you can manage classNames (myNode.addClass('foo')) and styles (myNode.setStyle('opacity', 0.5)), create elements (Y.Node.create('<div id="foo" class="foo"><p>foo</p></div>')), and much more.

Note: The method Y.get has been deprecated in favor of Y.one. The methods Node::query and Node::queryAll have been deprecated in favor of Node::one and Node::all. They still function as expected in this release, but support will be removed in a subsequent release.

Getting Started

Include Dependencies

The easiest way to include the source files for Node and its dependencies is to add the YUI seed file to your page, using the following script tag, and allow the YUI instance to download any additional files which may be required:

  1. <script src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"></script>
<script src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"></script>

The YUI instance will automatically pull down Node's source files and any missing dependencies when the node module is used. This helps you avoid having to manually manage the list of files needed on your page to support multiple components while also optimizing your initial page weight by loading files only when they are required.

If you do want to include file dependencies manually on your page, the YUI Dependency Configurator can be used to determine the list of files you need to include in order to use Node.

The YUI Instance

Once you have the YUI seed file on your page (yui-min.js), you can create a new YUI instance for your application to use and populate it with the modules you need, specified as the first set of arguments to the use method:

  1. // Create new YUI instance, and populate it with the required modules
  2. YUI().use('node', function(Y) {
  3.  
  4. // Node available, and ready for use.
  5.  
  6. });
// Create new YUI instance, and populate it with the required modules
YUI().use('node', function(Y) {
 
    // Node available, and ready for use.
 
});

The last argument passed to use is a callback function. The callback function will be invoked as soon as the YUI instance is done downloading any required files missing from your page. Once those files are loaded, your local YUI instance will be supplemented with the classes which make up the node module and any modules it depends on. A reference to the populated YUI instance (Y) is passed back to your callback function. Within your callback, then, you can start writing your application code based on your own custom instance of YUI.

For more information on creating instances of YUI and the use method, see the YUI Global object documentation.

Getting a Node

Node is the interface for DOM operations in YUI 3. The Node API is based on the standard DOM API, and provides additional sugar properties and methods that make common operations easier, and implementation code more concise. Developers familiar with the standard DOM API will find Node instances to be very familiar.

The simplest way to get a Node instance is using your YUI instance's one method. Y.one accepts either an existing DOM element or a selector query. If a selector query is used, the first matching element is used.

Note: CSS3 selector support is not included by default with Node, you will need to include the "selector-css3" module for CSS3 support.

This example demonstrates two ways to get a node instance.

  1. YUI().use('node', function(Y) {
  2. var node1 = Y.one('#main');
  3. var node2 = Y.one(document.body);
  4. });
YUI().use('node', function(Y) {
    var node1 = Y.one('#main');
    var node2 = Y.one(document.body);
});

Using Node

This section describes how to use the Node Utility in further detail. It contains these subsections:

Accessing Node Properties

Properties of the underlying DOM node are accessed via the Y.Node instance's set and get methods. For simple property types (strings, numbers, booleans), these pass directly to/from the underlying node, but properties that normally return DOM nodes return Y.Node instances instead.

This is an example of getting and setting various properties.

  1. YUI().use('node', function(Y) {
  2. var node = Y.one('#foo');
  3. var parent = node.get('parentNode'); // Node instance
  4.  
  5. var html = 'I am "' + node.get('id') + '".';
  6. html += 'My parent is "' + parent.get('id') + '"';
  7.  
  8. node.set('innerHTML', html);
  9. });
YUI().use('node', function(Y) {
    var node = Y.one('#foo');
    var parent = node.get('parentNode'); // Node instance
 
    var html = 'I am "' + node.get('id') + '".';
    html += 'My parent is "' + parent.get('id') + '"';
 
    node.set('innerHTML', html);
});

DOM Events

Use the on method to add an event listener to a Node instance. The event object passed as the first argument to each listener is an event facade that, like the Node API, normalizes browser differences and provides a standard API for working with DOM events based on the W3C standard. All properties of the event object that would normally return DOM elements return Y.Node instances

  1. YUI().use('node', function(Y) {
  2. Y.one('#demo').on('click', function(e) {
  3. e.preventDefault();
  4. alert('event: ' + e.type + ' target: ' + e.target.get('tagName'));
  5. });
  6. });
YUI().use('node', function(Y) {
    Y.one('#demo').on('click', function(e) {
        e.preventDefault();
        alert('event: ' + e.type + ' target: ' + e.target.get('tagName')); 
    });
});

DOM Methods

The Y.Node API provides all of the DOM methods you would expect, plus a few extras to help with common tasks. As with properties and events, any methods that would normally return DOM nodes instead return Y.Node instances.

  1. YUI().use('node', function(Y) {
  2. var node = Y.one('#demo');
  3. var node2 = node.appendChild(Y.one('#foo p'));
  4. node2.addClass('bar');
  5. });
YUI().use('node', function(Y) {
    var node = Y.one('#demo');
    var node2 = node.appendChild(Y.one('#foo p'));
    node2.addClass('bar');
});

Using NodeList

The Y.NodeList provides a node-like interface for manipulating multiple nodes through a single interface. The NodeList API is a pared-down version of the Node API, allowing for batching of common tasks.

The Y.all method is the simplest way to get a NodeList.

  1. YUI().use('node', function(Y) {
  2. Y.all('#demo li').addClass('bar');
  3. });
YUI().use('node', function(Y) {
    Y.all('#demo li').addClass('bar');
});

The Y.Node api returns NodeList instances when the DOM would normally return a collection of elements.

  1. YUI().use('node', function(Y) {
  2. Y.one('#demo').get('children').addClass('bar');
  3. });
YUI().use('node', function(Y) {
    Y.one('#demo').get('children').addClass('bar');
});

Node Queries

Selector queries are a powerful way to test and manipulate nodes. All Y.Node instances support one, all, and test.

  1. YUI().use('node', function(Y) {
  2. var node = Y.one('#demo');
  3.  
  4. var node2 = node.one('p');
  5. if (node2) { // might be null
  6. node2.addClass('bar'); // adds "bar" to the first paragraph descendant of #demo
  7. }
  8.  
  9. node.all('p').addClass('bar'); // adds "bar" to all paragraph descendants of #demo
  10.  
  11. if (node.test('.foo.bar')) { // "if node has both foo and bar classNames"
  12. node.removeClass('bar');
  13. }
  14. });
YUI().use('node', function(Y) {
    var node = Y.one('#demo');
 
    var node2 = node.one('p');
    if (node2) { // might be null
        node2.addClass('bar'); // adds "bar" to the first paragraph descendant of #demo
    }
 
    node.all('p').addClass('bar'); // adds "bar" to all paragraph descendants of #demo
 
    if (node.test('.foo.bar')) { // "if node has both foo and bar classNames"
        node.removeClass('bar');
    }
});

For more information on selector queries, see the following W3C specifications:

Note: CSS3 selector support is not included by default with Node, you will need to include the "selector-css3" module for CSS3 support.

ARIA Support

The Node interface has support for ARIA. When used with Node's built-in support for CSS selector queries, it is easy to both apply and manage a Node's roles, states and properties.

The ARIA Roles, States and Properties enhance the semantics of HTML, allowing developers to more accurately describe the intended purpose of a region of a page, or a DHTML widget, thereby improving the user experience for users of assistive technology, such as screen readers.

Apply any of the ARIA Roles, States and Properties via the set method. For example, to apply the role of toolbar to a <div> with an id of "toolbar":

  1. YUI().use('node', function(Y) {
  2. var node = Y.one('#toolbar').set('role', 'toolbar');
  3. });
YUI().use('node', function(Y) {
    var node = Y.one('#toolbar').set('role', 'toolbar');
});

Node's built-in support for CSS selector queries, method chaining, and ability to set multiple attributes on a single Node instance makes it especially easy to apply the ARIA Roles, States, and Properties when building DHTML widgets with a large subtree. For example, when building a menubar widget it is necessary to apply a role of menubar to the root DOM element representing the menubar, and the role of menu to the root DOM element representing each submenu. Additionally, as each submenu is hidden by default, the aria-hidden state will need to be applied to each submenu as well. The Node interface makes it possible to do all of this in one line of code:

  1. YUI().use('node', function(Y) {
  2. Y.one('#rootmenu').set('role', 'menubar').all('.menu').setAttrs({ role: 'menu', 'aria-hidden': true });
  3. });
YUI().use('node', function(Y) {
	Y.one('#rootmenu').set('role', 'menubar').all('.menu').setAttrs({ role: 'menu', 'aria-hidden': true });
});

Migration Table

Most of the functionality from YAHOO.util.Dom is available via Node.

Note In the snippets below, myNode is an instance of Node. Methods that normally would return DOM nodes now return Node instances.

2.x (via YAHOO.util.Dom) 3.0
addClass myNode.addClass
batch NodeList[methodName], NodeList.each, or Y.each
generateId Y.guid
get Y.one Note strings are now treated as selectors (e.g. "Y.one('#foo')" vs. "YAHOO.util.Dom.get('foo')")
getAncestorBy myNode.ancestor
getAncestorByClassName myNode.ancestor
getAncestorByTagName myNode.ancestor
getChildren myNode.get('children')
getChildrenBy myNode.all
getClientRegion myNode.get('viewportRegion')
getDocumentHeight myNode.get('docHeight')
getDocumentScrollLeft myNode.get('docScrollX')
getDocumentScrollTop myNode.get('docscrollY')
getDocumentWidth myNode.get('docWidth')
getElementsBy myNode.all
getElementsByClassName myNode.all
getFirstChild myNode.one
getFirstChildBy myNode.one
getLastChild myNode.one
getLastChildBy myNode.one
getNextSibling myNode.next
getNextSiblingBy myNode.next
getPreviousSibling myNode.previous
getPreviousSiblingBy myNode.previous
getRegion myNode.get('region')
getStyle myNode.getStyle
getViewportHeight myNode.get('winHeight')
getViewportWidth myNode.get('winWidth')
getX myNode.getXY
getY myNode.getXY
getXY myNode.getXY
hasClass myNode.hasClass
inDocument myNode.inDoc
insertAfter myNode.insert
insertBefore myNode.insert
isAncestor myNode.contains (Note myNode.contains(myNode) === true)
removeClass myNode.removeClass
replaceClass myNode.replaceClass
setStyle myNode.setStyle
setX myNode.setXY
setY myNode.setXY
setXY myNode.setXY

Support & Community

Forums & Blog

YUI 3 discussion forums are hosted on YUILibrary.com.

In addition, please visit the YUIBlog for updates and articles about the YUI Library written by the library's developers.

Filing Bugs & Feature Requests

The YUI Library's public bug tracking and feature request repositories are located on the YUILibrary.com site. Before filing new feature requests or bug reports, please review our reporting guidelines.

Copyright © 2010 Yahoo! Inc. All rights reserved. Copyright | Privacy Policy | Terms of Use | Job Openings