Jump to Table of Contents

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.

In addition to wrapping the basic DOM API and handling cross browser issues, Nodes provide convenient methods for managing CSS classes, setting or animating styles, subscribing to events, updating or dynamically loading content, and lots more.

Note: The Y.get(), node.query(), and node.queryAll() methods have been removed. Use Y.one(), node.one(), and node.all() or include the "node-deprecated" module in your use() statement to restore them.

Getting Started

To include the source files for Node and its dependencies, first load the YUI seed file if you haven't already loaded it.

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

Next, create a new YUI instance for your application and populate it with the modules you need by specifying them as arguments to the YUI().use() method. YUI will automatically load any dependencies required by the modules you specify.

<script>
// Create a new YUI instance and populate it with the required modules.
YUI().use('node', function (Y) {
    // Node is available and ready for use. Add implementation
    // code here.
});
</script>

For more information on creating YUI instances and on the use() method, see the documentation for the YUI Global Object.

Using Nodes

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.

Getting a Node

// Use Y.one( [css selector string] )
var node = Y.one('#main');

// Or pass an HTML element
var bodyNode = Y.one(document.body);

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 CSS selector. If a selector string is used, the first matching element is used. NodeLists are also available for working with collections of Nodes.

Note: CSS3 selector support is not included by default with Node. Add support by including the "selector-css3" module in your use() statement.

Creating Nodes and Modifying Content

// Create a new Node
var item = Y.Node.create('<li id="step3" class="highlight"><em>Profit</em></li>');

// Replace the content in a Node
Y.one("#hello").setHTML("<h1>Hello, <em>World</em>!</h1>");

// Append new markup inside a Node
bodyNode.append("<p>This is the end, beautiful friend, the end.</p>");

Nodes have methods for appending, prepending, replacing, and inserting content. The static method Y.Node.create() is provided to create new Nodes that you want to work with a bit more before attaching them to the DOM.

As noted in DOM Methods below, the standard DOM API methods, such as appendChild and insertBefore are also available to manipulate the DOM structure.

Accessing Node Properties

var imgNode = Y.one('#preview');
var labelNode = imgNode.get('nextSibling'); // Node instance

var bigSrc = thumbnail.get('src').slice(0, -4) + '-big.jpg';

imgNode.set('src', bigSrc);
imgNode.set('title', thumbnail.get('title');
labelNode.setHTML(thumbnail.get('title'));

Properties of the underlying DOM node are accessed via the 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 Node instances instead.

DOM Events

Y.one('#demo').on('click', function(e) {
    e.preventDefault();
    alert('event: ' + e.type + ' target: ' + e.target.get('tagName')); 
});

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 Node instances.

For more details, check out the Event user guide.

DOM Methods

var tasklist = Y.one('ul#tasklist');
var item3 = tasklist.appendChild( Y.one('#pending .item-3') );

item3.addClass('highlight');

The 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 Node instances.

Working With Collections of Nodes

NodeList is the class for working with groups of Nodes.

var doneTasks = Y.all('#tasklist .completed');

// NodeLists host most Node methods for simple iterative operations
doneTasks.removeClass('highlight');

// or call each() to do more work on each Node
doneTasks.each(function (taskNode) {
    taskNode.transition({ opacity: 0 }, function () {
        completedTasklist.appendChild(this);
    });
});

The Y.all method is the simplest way to get a NodeList, but throughout the library, any property or method that would return a collection of HTML elements will return a NodeList.

var nodelist = taskList.get('childNodes');

The 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 for simple operations, plus common Array methods such as slice() and pop() for modifying the internal list of wrapped Nodes, and some general purpose iteration methods such as each() and some().

Query a Node's Descendants

var node = Y.one('#demo');

var firstPara = node.one('p');

if (firstPara) { // might be null
    // adds "bar" to the first paragraph descendant of #demo
    firstPara.addClass('intro');
}

// adds class "syntax-highlight" to all <pre> descendants of #demo
node.all('pre').addClass('syntax-highlight');

Like Y.one() and Y.all(), Node instances have one() and all() methods for querying their descendants.

Using selectors to capture descendants is faster and more convenient than relying on DOM properties such as childNodes and nextSibling since you don't have to worry about working around text nodes or recursing into element subtrees.

Using one() and all() from a Node rather than Y can aid performance in large pages as well, because Y.one() and Y.all() always query from the document, which will scan a lot more elements.

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":

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:

Y.one('#root').set('role', 'menubar').all('.menu').setAttrs({ role: 'menu', 'aria-hidden': true });

Migration Table

The following table is included to help users migrating from YUI 2. 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 YAHOO.util.??? 3.0
Dom.get('elementId');
Y.one('#elementId');
Dom.getElementsBy(someFilterFunction);
myNode.all('selectorString');
Dom.getElementsByClassName('highlight');
myNode.all('.highlight');
Dom.getChildren(el);
myNode.get('children');
Dom.getChildrenBy(someFilterFunction);
myNode.all('selectorString');
Dom.getFirstChild(parentEl);
myNode.one('*');
Dom.getFirstChildBy(someFilterFunction);
myNode.one('> selectorString');
Dom.getLastChild(el);
Dom.getLastChildBy(someFilterFunction);
myNode.get('children').slice(-1).item(0);
// OR target the node with a selector
myNode.one('> selector:last-of-type');
Dom.getNextSibling(el);
Dom.getNextSiblingBy(someFilterFunction);
Dom.getPreviousSibling(el);
Dom.getPreviousSiblingBy(someFilterFunction);
myNode.next();
myNode.next('selectorString');
myNode.previous();
myNode.previous('selectorString');
Dom.getAncestorBy(someFilterFunction);
Dom.getAncestorByClassName('highlight');
Dom.getAncestorByTagName('pre');
myNode.ancestor(someFilterFunction);
myNode.ancestor('.highlight');
myNode.ancestor('pre');
Dom.isAncestor(ancestorEl, el);
ancestorNode.contains(myNode);
Dom.insertAfter(el, afterEl);
Dom.insertBefore(el, beforeNode);
afterNode.insert(myNode, 'after');
beforeNode.insert(myNode, 'before');
Dom.addClass('highlight');
myNode.addClass('highlight');
Dom.removeClass(el, 'highlight');
myNode.removeClass('highlight');
Dom.replaceClass(el, 'high', 'low');
myNode.replaceClass('high', 'low');
Dom.hasClass(el, 'highlight');
myNode.hasClass('highlight');
Dom.getStyle(el, 'backgroundColor');
myNode.getStyle('backgroundColor');
Dom.setStyle(el, 'borderColor', '#C0FFEE');
myNode.setStyle('borderColor', '#C0FFEE');
Dom.getXY(el);
Dom.getX(el);
Dom.getY(el);
myNode.getXY();
myNode.getX();
myNode.getY();
Dom.setXY(el, [ 500, 300 ]);
Dom.setX(el, 500);
Dom.setY(el, 300);
myNode.setXY([ 500, 300 ]);
myNode.setX(500);
myNode.setY(300);
Dom.inDocument(el);
myNode.inDoc();
Dom.batch(elementArray,
    Dom.addClass, 'highlight');
myNodelist.addClass('highlight');
// OR
myNodelist.each(function (node) {
    node.addClass('highlight')
});
// OR
Y.Array.each(myNodelist, function (node) {
    node.addClass('highlight');
});
Dom.generateId();
Y.guid();
Dom.getViewportHeight();
Dom.getViewportWidth();
myNode.get('winHeight');
myNode.get('winWidth');
Dom.getDocumentHeight();
Dom.getDocumentWidth();
myNode.get('docHeight');
myNode.get('docWidth');
Dom.getClientRegion();
myNode.get('viewportRegion');
Dom.getRegion(el);
myNode.get('region');
Dom.getDocumentScrollLeft();
Dom.getDocumentScrollTop();
myNode.get('docScrollX');
myNode.get('docScrollY');