Introducing YUI

Post on 15-Jan-2015

5368 Views

Category:

Education

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

An introduction to YUI and some examples of how to use it to solve daily problems in web design. A talk given at the University in Bucharest and partly re-hashed on the flight from my Ajax Experience talk.

Transcript

Introducing YUI

Christian Heilmann

Bucharest, Romania, November 2008

Hello there, I am Chris.

I am here today to talk about the Yahoo User Interface

library (YUI)http://developer.yahoo.com/yui/

What is the most annoying thing about web

development?

The undefined environment.

This is also the coolest thing about web development.

Don’t ever delude yourself into thinking you can control what people see when they

visit your web products.

However, you want your products to work.

The working bit is what I want to talk to you about.

When you start writing a web document, you use HTML and

hope browsers do things right.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Here’s my title</title> <meta name="description" content="Description"></head><body></body></html>

The right DOCTYPE, encoding and language is a great start.

This is an unstyled document, right?

Wrong.

There is no such thing as an unstyled document.

There is no such thing as an “unstyled page”.

This differs from browser to browser and can be *very*

annoying!

Which is why YUI offers you reset.css

http://developer.yahoo.com/yui/reset/

Starting with a blank canvas is a good start.

What about typography?

Make it work across browsers with fonts.css

http://developer.yahoo.com/yui/fonts/

Even create layouts with grids.css

http://developer.yahoo.com/yui/grids/

All of this with one line of code pulling a document

from the web.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Here’s my title</title> <meta name="description" content="Description"> <link rel="stylesheet" href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css"></head><body></body></html>

What if that file is not available?

First of all, this is not a single server, but a world-wide

network of servers.

Visitors of your site will get the files from the server geographically located

nearest to them.

This is Yahoo’s network, but you can also use Google’s!

http://yuiblog.com/blog/2008/11/19/yui-google/

If you like full control, then you can also host the files

yourself (this will also make them work off-line!)

Let’s play with grids a bit.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Here’s my title</title> <link rel="stylesheet" href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css"></head><body>

<div id="doc" class="yui-t4"> <div id="hd">Header</div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> Main section </div> </div> <div class="yui-b"> Sidebar </div> </div> <div id="ft"><p>Footer</p></div></div></body></html>

You divide the document in three parts: a head, a body

and a footer.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Here’s my title</title> <link rel="stylesheet" href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css"></head><body>

<div id="doc" class="yui-t4"> <div id="hd">Header</div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> Main section </div> </div> <div class="yui-b">

Sidebar </div> </div> <div id="ft"><p>Footer</p></div></div></body></html>

You then define a side bar and a main part.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Here’s my title</title> <link rel="stylesheet" href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css"></head><body>

<div id="doc" class="yui-t4"> <div id="hd">Header</div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> Main section </div> </div> <div class="yui-b">

Sidebar </div> </div> <div id="ft"><p>Footer</p></div></div></body></html>

Both are identical, the only difference is that the main

part has to be wrapped in a DIV with the ID “yui-main”.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Here’s my title</title> <link rel="stylesheet" href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css"></head><body>

<div id="doc" class="yui-t4"> <div id="hd">Header</div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> Main section </div> </div> <div class="yui-b">

Sidebar </div> </div> <div id="ft"><p>Footer</p></div></div></body></html>

The order of the two doesn’t matter!

The sidebar is a predefined width, the main section takes

up the rest of the space.

You define the overall width of the document with an ID

and the location and width of the sidebar with a class on

the containing DIV.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Here’s my title</title> <link rel="stylesheet" href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css"></head><body>

<div id="doc" class="yui-t4"> <div id="hd">Header</div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> Main section </div> </div> <div class="yui-b">

Sidebar </div> </div> <div id="ft"><p>Footer</p></div></div></body></html>

#doc = 750px

#doc2 = 950px

#doc3 = 100%

#doc4 = 974px

.yui-t1 = left 160px

.yui-t2 = left 180px

.yui-t3 = left 300px

.yui-t4 = right 180px

.yui-t5 = right 240px

.yui-t6 = right 300px

ID and width class, side and width

You can add grid units inside the main section to divide it

into horizontal columns.

Check the docs at:http://developer.yahoo.com/yui/grids

Or if you are lazy...

Use the grids builder:

So where does this work?

In all the browsers Yahoo has to support.

Which are defined in our graded browser support:

http://developer.yahoo.com/yui/articles/gbs/

What if a new browser comes around?

Chances are very high Yahoo will have to support it...

...so check the YUI blog and update your YUI CSS include.

http://yuiblog.com

Much faster than fixing everything yourself, right?

What if HTML is not rich enough for your needs?

Almost all *free* and *big* JavaScript libraries come

with widgets that work and are proven in the market.

YUI is of course one of them.

AutoComplete

Button

Calendar

Carousel beta

Charts [experimental]

Color Picker

Container

DataTable

ImageCropper beta

Layout Manager

Menu

Paginator

Rich Text Editor

Slider

TabView

TreeView

Uploader [experimental]

Of course the other thing the YUI makes a lot easier is

using JavaScript.

Both by fixing annoying browser bugs and by offering

convenience methods.

For example:

Wouldn’t it be cool to not know when to use which size

of the grid automatically?

You can do that using YUI DOM.

http://developer.yahoo.com/yui/dom

Using the DOM component, I can read out what happens in

the browser.

I can get the dimensions of the window, the browser and of

any element in the document - regardless of its positioning.

Thus I can create a YUI grid that works with all kind of different browsers sizes.

YAHOO.example.autoGrid = function(){ var container = YAHOO.util.Dom.get('doc') || YAHOO.util.Dom.get('doc2') || YAHOO.util.Dom.get('doc4') || YAHOO.util.Dom.get('doc3') || YAHOO.util.Dom.get('doc-custom'); if(container){ var sidebar = null; var classes = container.className; if(classes.match(/yui-t[1-3]|yui-left/)){ var sidebar = 'left'; } if(classes.match(/yui-t[4-6]|yui-right/)){ var sidebar = 'right'; } function switchGrid(){ var currentWidth = YAHOO.util.Dom.getViewportWidth();

if(currentWidth > 950){ container.id = 'doc2'; if(sidebar){ container.className = sidebar === 'left' ? 'yui-t3' : 'yui-t6'; } } if(currentWidth < 950){ container.id = 'doc'; if(sidebar){ container.className = sidebar === 'left' ? 'yui-t2' : 'yui-t5'; } } if(currentWidth < 760){ container.id = 'doc3'; if(sidebar){ container.className = sidebar === 'left' ? 'yui-t1' : 'yui-t4'; } }

if(currentWidth < 600){ container.id = 'doc3'; container.className = ''; } }; switchGrid(); function throttle(method, scope) { clearTimeout(method._tId); method._tId= setTimeout(function(){ method.call(scope); }, 100); }; YAHOO.util.Event.on(window,'resize',function(){ throttle(YAHOO.example.autoGrid.switchGrid,window); });

}; return { switchGrid:switchGrid };}();

What about monitoring the size of an element?

position:fixed is sexy!

It can however also render your site impossible to use.

var YD = YAHOO.util.Dom; YAHOO.util.Event.onDOMReady(toggleMenu); YAHOO.util.Event.on(window,'resize',function(){ toggleMenu(); }); function toggleMenu(){ var sidebar = YD.getRegion('sb'); var browser = YD.getViewportHeight(); YD.setStyle('sb','position', browser < sidebar.bottom ? 'static' : 'fixed' ); }

The DOM stepchild: Region

Using Region I can find out the dimensions of an element.

I can also find the region that is big enough to include two

regions, or the one that is the intersection of the two.

region example

YAHOO.util.Event.onDOMReady(function(){ var YD = YAHOO.util.Dom; var r1 = YD.getRegion('region-one'); var r2 = YD.getRegion('region-two'); var i = r1.intersect(r2); var u = r1.union(r2); var intersect = document.createElement('div'); document.body.appendChild(intersect); YD.setStyle(intersect,'position','absolute'); YD.setStyle(intersect,'background','#c0c'); YD.setStyle(intersect,'width',i.right-i.left + 'px'); YD.setStyle(intersect,'height',i.bottom-i.top + 'px'); YD.setStyle(intersect,'z-index',100); YD.setXY(intersect,i);

var union = document.createElement('div'); document.body.appendChild(union); YD.setStyle(union,'position','absolute'); YD.setStyle(union,'background','#000'); YD.setStyle(union,'opacity',.5); YD.setStyle(union,'width',u.right-u.left + 'px'); YD.setStyle(union,'height',u.bottom-u.top + 'px'); YD.setStyle(union,'z-index',90); YD.setXY(union,u); });

This gives me full control to avoid any overlap!

What about things the browser does not tell me?

Wouldn’t it be cool to find out when the font is resized?

You can detect the font size in several ways:

Include an element with a known size in ems and read its

offsetHeight and offsetWidth in an interval...

...or use an iframe with em sizing off-screen and subscribe

to its resize event.

Or use the YUI container module anywhere on your

page... :)

YAHOO.namespace('example.container'); YAHOO.util.Event.onDOMReady(function(){ YAHOO.example.container.module1 = new YAHOO.widget.Panel( 'module1', { close:true, draggable:true, constraintoviewport:true } ); YAHOO.example.container.module1.render(); YAHOO.widget.Module.textResizeEvent.subscribe( function(o){ console.log('Text has been resized!') } ); });

YAHOO.namespace('example.container'); YAHOO.util.Event.onDOMReady(function(){ YAHOO.example.container.module1 = new YAHOO.widget.Panel( 'module1', { close:true, draggable:true, constraintoviewport:true } ); YAHOO.example.container.module1.render(); YAHOO.widget.Module.textResizeEvent.subscribe( function(o){ console.log('Text has been resized!') } ); });

This works with one feature of YUI event that is very close to

my heart: Custom Events.

Custom Events allow you to notify an unknown amount of

listeners about what is happening...

... sending information not necessarily accessible to them

when it happens.

Every single YUI component has a lot of Custom Events you

can subscribe to.

Say for example you want to make sure to securely chain

animation sequences...

//This is the first animation; this one will //fire when the button is clicked. var move = new YAHOO.util.Anim("animator", { left: {from:0, to:75} }, 1); //This is the second animation; it will fire //when the first animation is complete. var changeColor = new YAHOO.util.ColorAnim( "animator", { backgroundColor: {from:"#003366", to:"#ff0000"} }, 1); //Here's the chaining glue: We subscribe to the //first animation's onComplete event, and in //our handler we animate the second animation: move.onComplete.subscribe(function() { changeColor.animate(); });

//Here we set up our YUI Button and subcribe to //its click event. When clicked, it will //animate the first animation: var start = new YAHOO.widget.Button("startAnim"); start.subscribe("click", function() { //reset the color value to the start so that //the animation can be run multiple times: YAHOO.util.Dom.setStyle("animator", "backgroundColor", "#003366"); move.animate(); });

//You can also make use of the onStart and onTween //custom events in Animation; here, we'll log all //of changeColor's custom events and peek at their //argument signatures: changeColor.onStart.subscribe(function() { YAHOO.log("changeColor animation is starting.", "info", "example"); }); changeColor.onTween.subscribe(function(s, o) { YAHOO.log("changeColor onTween firing with these arguments: " + YAHOO.lang.dump(o), "info", "example"); }); changeColor.onComplete.subscribe(function(s, o) { YAHOO.log("changeColor onComplete firing with these arguments: " + YAHOO.lang.dump(o), "info", "example"); });

Knowing when something happens and being able to

react to it is much safer than assuming it worked.

Knowledge is power.

This is why YUI comes with a lot of tools to gain knowledge

about what is happening under the hood of your

application.

YUI Logger gives you a cross-browser console to show

values.

Death to alert()!

All YUI components come as a debug version which log

everything that is going on to the logger.

You can even include the logger on the fly with a

bookmarklet.

If you need even more control, there is the YUI

profiler.http://developer.yahoo.com/yui/profiler/

And the YUI test framework for test driven development.

http://developer.yahoo.com/yui/yuitest/

On a code level, YUI comes out-of-the-box with

namespacing.

Which – if used correctly – keeps large amounts of code readable and maintainable.

YAHOO.lang also comes with a lot of validation methods to ensure things are what they

are.

So how is YUI good for professional and easy

development?

Built on agreed standards

Separated into modules each dealing with one task

Constant reporting of what is going on

Own Debugging environment

Here’s another small thing I prepared earlier:

Using Event and Dom I can control the visible part:

function move(e){ y = YAHOO.util.Event.getXY(e); if(y[1] > size){ render(y); } }; function render(y){ var d = YAHOO.util.Dom; var real = y[1] - d.getDocumentScrollTop(); d.setStyle(top,'height',real-size+'px'); d.setStyle(bottom,'top',real+size+'px'); var h = d.getViewportHeight() - real + size; d.setStyle(bottom,'height',h + 'px'); };

What does the future hold?

YUI3http://developer.yahoo.com/yui/3/

Include on demand

Multiple sandboxed instances in a page

Modularity on CSS level (per element reset)

Every event is a custom event

Christian Heilmann

http://wait-till-i.com | http://scriptingenabled.org

http://twitter.com/codepo8

THANKS!

top related