
YUI 3 Introduction
kenjiru.ro@gmail.com
Overview
- Loader
- Modules
- DOM manipulation
- Event system
- Component infrastructure
- Y.Base
- Attributes
- Plugins
- Widgets
What is YUI 3
- YUI stands for Yahoo User Interface Library
- JavaScript library that simplifies development
- First release in 2006
- Developed by Yahoo engineers
Checkout yuilibrary.com
The Seed File
Seed file:
- YUI core
- Loader
- metadata for additional YUI modules
Include the YUI seed file in your HTML:
<script src="http://yui.yahooapis.com/3.10.1/build/yui/yui-min.js"></script>More Seed Files
The Base Seed file:
- YUI core
- the Get utility
- no Loader, no metadata
<script src="http://yui.yahooapis.com/3.10.1/build/yui-base/yui-base-min.js"></script>
The Core Seed file:
-
YUI core
- the smallest seed file
- not capable of dynamically loading other modules
<script src="http://yui.yahooapis.com/3.10.1/build/yui-core/yui-core-min.js"></script>The Loader
Loader:
- loads JavaScript and CSS files
- can load external modules
- resolves dependencies automatically
- loads files asynchronous (default) or synchronous
Using modules
Using a module:
YUI().use('node', function(Y) {
Y.one('#myDiv').set('text', 'Foo');
});
The workflow:
- create a new YUI instance calling YUI()
- call use() on the new YUI instance
- loads any necessary modules
- attaches them to the YUI instance
- executes the modules
- executes our callback method
More Use Cases
Using multiple modules:
YUI().use('node', 'anim', function(Y) {
Y.one('#myDiv').set('text', 'Foo');
new Y.anim({ node: '#mySpan', to: {opacity: 0} });
});
Attach modules to an existing instance:
YUI().use('calendar', function (Y) {
// the 'calendar' module is available here
Y.use('autocomplete', function () {
// both 'calendar' and 'autocomplete' modules are now available
});
});
Defining a Module
The general pattern:
YUI.add('foo', function(Y) {
var privateProperty = 'something';
function privateMethod() {
};
Y.foo = {
privateProperty : 'private',
privateMethod : function() {
}
};
}, '0.1', { requires: ['node'] });
Advantages:
- helps structuring the code
- encapsulates private code
DOM Manipulation
Y.Node is the interface for DOM operations:
- wraps the basic DOM API
- handles cross browser issues
- provides convenient methods for
- managing CSS classes
- setting or animating styles
- subscribing to events
- updating or dynamically loading content
- and a lot more
- the API is very similar to jQuery
Check out jsrosettastone.com
Y.node
Getting a node:
var node = Y.one('#main'); // Node instance
var spans = Y.all('span'); // NodeList instance
var specialSpan = spans.one('#special');
var selectedSpans = spans.all('.selected');
Creating nodes and modifying content:
var div = Y.Node.create('<div id="main"><i>Foo</i></div>');
Y.one('#foo').setHTML('<b>Foo</b>');
Y.one('#bar').append('<span>bar</span>');
Accessing node properties:
var imgNode = Y.one('#preview');
imgNode.set('title', 'Small thumbnail..');
var src = imgNode.get('src');
Y.NodeList
Working with collections of nodes:
var spans = Y.all('#main span');
// NodeLists host most Node methods for simple iterative operations
spans.removeClass('highlight');
spans.setAttribute('foo', 'bar');
// or call each() to do more work on each Node
spans.each(function (span) {
span.transition({ opacity: 0 }, function () {
// ...
});
});
Event System
- provides APIs for browser's DOM event system
- fixes events that behave differently across browsers
- synthetic event system supplies entirely new DOM events
- the user can create custom events
Basic examples:
Y.on('click', function(e) {
// handle the event
}, '#myNode', context);
myButton.on('click', function(e) {
// handle the event
}, context);
The Event Object
button.on('click', function (e) {
this.get('id'); // Node instance, the button being clicked
e.target.get('id'); // Node instance
// Stop the event's default behavior
e.preventDefault();
// Stop the event from bubbling up the DOM tree
e.stopPropagation();
});
Detaching subscription:
var sub = button.on('click', handleClick);
sub.detach(); // unbinds the event
button.detach('click', handleClick); // alternative for unbinding
Event Delegation
Advantages:
- one event subscription handles multiple elements
- the filtering logic is build-in as a CSS selector
// delegated subscription for all button clicks from inside the node
node.delegate('click', function() {
this.get('id'); // now this refers to the button that was clicked
}, 'button, input[type=button]');
One time subscriptions:
Y.once('click', callback, '#myDiv');
node.once('click', callback);
The subscription will automatically be detached after the event fires.
Custom Events
this.fire('eventName', { foo : 'foo' });
// handling the event
myObject.on('eventName', function(e) {
console.log(e.foo);
});
Advantages:
- normalized API
- subscribe as on and after
- can have cancelable default behaviors
- can bubble
Component Infrastructure
Consists of:
- Y.Base
- Y.Attribute
- Y.Plugin
- Y.Widget
Y.Base
- low level class
- Attribute and Event based
- consistent init() and destroy() lifecycle
function MyClass(config) {
// Invoke Base constructor, passing through arguments
MyClass.superclass.constructor.apply(this, arguments);
}
MyClass.NAME = "myClass";
MyClass.ATTRS = {
myAttribute : { }
};
Y.extend(MyClass, Y.Base, {
// Prototype methods for your new class
myMethod : function() { }
});
Y.Base.create
var MyClass = Y.Base.create('myClass', Y.Base, [], {
initializer : function(config) {
// initialization here
},
prototypeMethod : function() {
this.set('foo', 'some value');
},
destructor : function() {
// cleanup here
}
}, {
ATTRS : {
foo : {}
},
staticMethod : function() {}
});
Attributes
- get() and set() methods
-
getters, setters and validators
- change events when attribute values change
-
read-only or write-once
Setting and getting attributes:
myObject.set('attrA', 6);
myobject.get('attrA');
Attribute configuration
this.addAttr("attrA", {
value: 5,
setter: function(val) {
return Math.min(val, 10);
},
validator: function(val) {
return Y.Lang.isNumber(val);
}
});
this.addAttrs({
attrA: {},
attrB: {}
}, userValues);
More about attribute configuration.
Attribute Change Events
Custom Events, having the type: "[attributeName]Change"
myObject.on('enabledChange', function(event) {
// Do something just before 'enabled' is about to be set
var val = event.prevVal; // the current attribute value
if (val < 10) {
event.newVal = val + 10; // or set a new value
} else {
event.preventDefault(); // can prevent the set action
}
});
myObject.after("nameChange", function (event) {
// Do something after 'enabled' was set
});
Plugin
function AnchorPlugin(config) {
this._node = config.host;
}
AnchorPlugin.NS = "anchors"
AnchorPlugin.prototype = {
disable: function() {
var node = this._node,
anchors = node.queryAll("a");
anchors.addClass("disabled");
anchors.setAttribute("disabled", true);
}
};
var container = Y.one("#myDiv");
container.plug(AnchorPlugin); // attach the plugin
container.anchors.disable(); // execute a method
Y.Plugin.Base
- extends Y.Base (attributes, life cycle, custom events)
- sets up host as an attribute
- can listen for and react to events fired by the host
-
onHostEvent(), afterHostEvent()
- listeners are automaticaly cleaned up when unplugging
- can inject logic before or after methods invoked on the host (using YUI 3 AOP)
-
beforeHostMethod(), afterHostMethod()
- can prevent the default method from being executed
Y.Widget
- the base class of all YUI 3 widgets
- like width, height, visible, focused and disabled
- see the documentation
- adds a render lifecycle
- a common set of widget attributes
- progressive enhancement
- string localization
The Render Lifecycle
The renderer() method implementation:
renderer: function() {
this.renderUI();
this.bindUI();
this.syncUI();
}
Rendered Markup:
- boundingBox and contentBox attributes
- BOUNDING_TEMPLATE and CONTENT_TEMPLATE prototype properties
Class names:
var class = this.getClassName("hidden"); // yui3-tooltip-hidden
Sample Widget
var Tooltip = Y.Base.create('tooltip', Y.Widget, [ ], {
CONTENT_TEMPLATE : '<span></span>',
renderUI : function() {
var text = this.get('text');
this.get('contentBox').set('text', text);
},
bindUI : function() {
var targetNode = this.get('targetNode');
targetNode.on('mouseover', this.show, this);
targetNode.on('mouseout', this.hide, this);
}
}, {
ATTRS : {
targetNode : null,
text : { value : 'Default text' }
}
});
HTML Output
Sample output:
<div id="yui_12" class="yui3-widget yui3-tooltip yui3-widget-positioned yui3-widget-stacked yui3-tooltip-hidden">
<span id="yui_14" class="yui3-tooltip-content">Tooltip 4</span>
</div>
YUI 3 Introduction
By kenjiru
YUI 3 Introduction
Presentation of YUI 3
- 1,319