Welcome to the YUI library! This tutorial contains everything you need to get up and running quickly with YUI. If you've never used YUI before, but you perhaps have a little experience with plain JavaScript or JavaScript frameworks, read onward.
Note that if you have experience with jQuery, it is a great idea to read or at least skim through the JS Rosetta Stone, which demonstrates how common jQuery and YUI idioms map to each other. The good news is that in the areas where YUI and jQuery overlap, you'll find that it is not too difficult to translate back and forth between the two.
The easiest way to get started with YUI is to use SimpleYUI, a convenient package for working with DOM nodes, events, UI effects, and AJAX.
All examples in this tutorial are variations on a minimal but valid HTML5 document that resembles:
<!DOCTYPE html>
<title>{Example Title}</title>
<style>/* {Example CSS styles} */</style>
<div id="demo"></div>
<script src="http://yui.yahooapis.com/3.6.0/build/simpleyui/simpleyui-min.js"></script>
<script>
/* {Example code} */
</script>
In this skeleton document, the first <script>
element does two things:
-
It pulls in the minified, gzipped SimpleYUI file from Yahoo's CDN. While you can always download and store a local copy of YUI, using the CDN is faster and more convenient.
-
It instantiates a global YUI object named
Y
for immediate use. You can access the entire YUI library through this object.
The second <script>
element is where your custom JavaScript code goes. Let's start by using YUI to change the page's appearance.
The Y.one()
method is a workhorse method for selecting and manipulating a single element on the page. Y.one()
takes a CSS selector and returns a Node object. Once you have a Node
reference, it is easy to change its properties by calling additional methods.
Example 1 uses YUI to add a class to a <div>
, turning it red.
<!DOCTYPE html>
<title>Highlighting a Single Element</title>
<style>
.highlight { background: #f66; color: #fff; }
</style>
<div id="demo">All for one and one for all!</div>
<script src="http://yui.yahooapis.com/3.6.0/build/simpleyui/simpleyui-min.js"></script>
<script>
Y.one('#demo').addClass('highlight');
</script>
Y.one()
selects the element with an id
of demo
and creates a Node
object to represent it. The code then calls the addClass() method, which adds the .highlight
class to the element. If you load the document with JavaScript enabled, the <div>
is highlighted red. If you load the document with JavaScript disabled, nothing special happens.
Of course, you could easily just highlight the <div>
with CSS alone. Let's try something a little more interesting.
In Example 2, the <div>
starts out unstyled. But as soon you click anywhere in the document, the <div>
turns red.
<!DOCTYPE html>
<title>Highlighting a Single Element On Click</title>
<style>
.highlight { background: #f66; color: #fff; }
</style>
<div id="demo">All for one and one for all!</div>
<script src="http://yui.yahooapis.com/3.6.0/build/simpleyui/simpleyui-min.js"></script>
<script>
function highlightDiv(ev) {
Y.one('#demo').addClass('highlight');
};
Y.one('document').on('click', highlightDiv);
</script>
This example calls Y.one()
twice. The first call is the same as before: it selects the element with an id
of demo
, so that you can add the .highlight
class. This line is now wrapped in a function named highlightDiv
.
The example then attaches an event to the document by calling the on() method, which requires at least two arguments:
- A string indicating the event to listen for (such as
click
ormouseover
). - An event handler function to trigger when the event occurs.
In Example 2, the event is a click
event anywhere in the document, and the function to trigger is highlightDiv()
. If you click anywhere in the document, the browser executes highlightDiv()
, which turns the <div>
red, just like Example 1.
Note that Example 2 uses a named function to handle the event. A convenient way to work with event handlers is to use anonymous (nameless) functions. Anonymous functions are common in JavaScript, but if you're coming to this tutorial from another language, they might look unfamiliar. Rewritten with an anonymous function, the code would look like this:
Y.one('document').on('click', function (ev) {
Y.one('#demo').addClass('highlight');
});
If you use Y.one()
to fetch an element that does not exist, the method returns null
. This makes Y.one()
useful for doing existence checks:
if (Y.one('#some-node')) {
// do something
} else {
// do something else
}
If multiple elements match your Y.one()
call, Y.one()
returns the first one in the document that matches. If you actually want to operate on some or all of the elements, YUI provides a different method, Y.all()
, discussed below.
The Y.all()
method is similar to Y.one()
, except that when you give it any CSS selector, it selects and returns multiple nodes as a NodeList object. For example:
Y.all('p');
returns a NodeList
containing all paragraphs in the document. The NodeList
provides an each()
method that enables you to iterate over each node in the list, applying a function:
function highlightPara(node) {
node.addClass('highlight');
}
Y.all('p').each(highlightPara);
The each()
method supplies the current node as highlightPara
's first argument, enabling you to call addClass()
on each node.
Alternatively, you can do the same thing using an anonymous function:
Y.all('p').each(function (node) {
node.addClass('highlight');
});
which is a little more compact.
Conveniently, a number of NodeList
methods are similar to Node
methods. For example, NodeList
's addClass()
method does essentially the same thing as the Node
's, except that it adds a class to every node in the list. This means that if you're doing a common task like adding a class, your code can be even more compact:
Y.all('p').addClass('highlight');
Note that even if there are no <p>
elements on the page, the line above is completely safe to use. Y.all()
always returns a NodeList
-- if nothing matches the selector, the list is just empty. This means that you can always directly call addClass()
or each()
or otherwise iterate over a Y.all()
without having to inspect the results first.
Y.one()
and Y.all()
enable you to reach into the DOM and grab a node reference using CSS selectors. Once you have a node reference, you can call additional methods to walk the DOM tree.
For example, you can get a reference to the first <ul>
that has a class of navigation
, and then get all child list items:
var nav = Y.one('ul.navigation');
var navItems = node.all('li');
This code snippet is equivalent to:
var navItems = Y.all('ul.navigation li');
Calling one()
or all()
from a node walks down the DOM tree. To walk up the tree, call ancestor()
for the first ancestor that matches the query, or ancestors()
for all ancestors that match the query. For example, if you have a handle to some text <input>
node, you can get the <form>
element that it belongs to with:
var textfield = Y.one('#some-text-field');
var form = textfield.ancestor('form');
To walk sideways, call next()
or previous()
. These methods are like native DOM nextSibling() and previousSibling(), but they always return a sibling element as a YUI node, and they ignore adjacent text nodes in all browsers.
var listItem = Y.one('#some-listitem-id');
var nextListItem = listItem.next(); // a list item, not a text node
Once you select some nodes using Y.one()
, Y.all()
, or one of the methods described under "Walking the DOM" above, you can do a lot more than just adding and removing classes. For instance, you can completely rewrite the inner content of the node, as shown in Example 3:
<!DOCTYPE html>
<title>Appending an Element</title>
<p>
<button id="append">Append HTML</button>
<button id="replace">Set HTML</button>
</p>
<ul id="demo">
<li>This is the first bullet.</li>
</ul>
<script src="http://yui.yahooapis.com/3.6.0/build/simpleyui/simpleyui-min.js"></script>
<script>
Y.one('#append').on('click', function (ev){
Y.one('#demo').append('<li>HELLO!</li>');
});
Y.one('#replace').on('click', function (ev) {
Y.one('#demo').setHTML('<li>GOODBYE!</li>');
});
</script>
append()
inserts the supplied string or element as the node's last child, while setHTML()
replaces all of the node's content with the new string or element. Thus, clicking the "Append HTML" button adds new list items, while clicking the "Set HTML" button blows away the contents of the <ul>
and replaces them with a single list item. Both methods automatically convert strings of HTML markup (such as "<p>Some text</p>"
) to HTML before doing the insert.
Hiding a node in YUI is straightforward. Just call the hide()
method:
Y.one('#demo').hide();
This hides the node immediately. You can also choose to fade the node away gradually by passing a flag in to the hide()
method:
Y.one('#demo').hide(true);
More generally, you can roll your own CSS animations using the transition()
method. This method takes two parameters:
- A configuration object describing how the transition should behave and the the CSS properties to transition to
- An optional callback function to execute when the transition completes
Creating your own custom fade transition is straightforward. The simplest thing to do is transition the node from its current CSS opacity to 0:
Y.one('#demo').transition({ opacity:0 });
If you try out this transition, you'll notice that the node fades from view pretty quickly. This might work well for certain use cases, such as dismissing a dialog box. However, if you want to slow down the fade or otherwise control its behavior, you can provide more configuration information:
Y.one('#demo').transition({
duration: 2,
delay: 1,
easing: 'ease-out',
opacity: 0
});
This changes the behavior as follows:
- Increases the transition's duration to two seconds, from the YUI default of 0.5 seconds.
- Adds a delay before starting the transition of 1 second. The YUI default is 0 seconds.
- Changes the easing algorithm to
ease-out
, which begins the transition quickly and then decelerates at the end. You can also specify other options such asease-in
, which begins the transition slowly and accelerates at the end.
While the above transitions cause the node to fade and disappear, the node is still present in the DOM. To remove the node entirely after the fade completes, add a callback function:
Y.one('#demo').transition({
duration: 2,
delay: 1,
easing: 'ease-out',
opacity: 0
}, function() {
this.remove();
});
Beyond simply messing with the node's opacity, you can also construct transitions that operate on several CSS properties at once. For example, this transition changes the height, width, and background color of the node simultaneously:
Y.one('#demo').transition({
duration: 2,
delay: 1,
easing: 'ease-out',
height: '150px',
width: '300px',
backgroundColor: '#c00'
});
For even more fine-grained control, you can set separate durations, delays, and easings on each CSS property. Example 4 puts it all together:
<!DOCTYPE html>
<title>Basic Transition</title>
<style>
#demo {
width: 100px;
height: 100px;
border: 1px solid black;
padding: 5px;
background: #009;
}
</style>
<div id="demo"></div>
<script src="http://yui.yahooapis.com/3.6.0/build/simpleyui/simpleyui-min.js"></script>
<script>
Y.one('#demo').transition({
duration: 2,
easing: 'ease-in',
height: {
duration: 1,
delay: 1,
easing: 'ease-out',
value: '150px'
},
width: '300px',
backgroundColor: {
duration: 1,
delay: 2,
value: '#c00'
}
});
</script>
The height
and background
properties have their own duration
, delay
, and easing
settings, which override the values set at the top.