In this session, Aaron Gustafson introduces attendees to the client-side scripting language known as JavaScript. After being taken on a quick tour through the language's features and syntax, attendees will be introduced through a series of examples to ways in which JavaScript can progressively enhance the user experience and really make their designs sing. This session also introduces attendees to several JavaScript libraries and demonstrate how to execute the same task in each.
3. FUNDAMENTAL JAVASCRIPT
DHTML
๏ …was all about animation and interactivity
๏ ...was invented by marketing wonks
๏ ...is really three technologies: JavaScript, CSS & HTML
๏ ...carried a lot of baggage: browser-specific, forked code,
screen only & non-standard markup
๏ ...was a maintenance nightmare
IN CONTROL 2009 3
4. FUNDAMENTAL JAVASCRIPT
DOM Scripting
๏ …is the web standards approach to manipulating documents
๏ ...only requires a scripting language and valid markup
๏ ...is browser independent
๏ ...makes use of progressive enhancement
๏ ...just makes sense
IN CONTROL 2009 4
5. FUNDAMENTAL JAVASCRIPT
The document
<!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Strict//ENquot;
quot;http://www.w3.org/TR/XHTML1/DTD/XHTML1-strict.dtdquot;>
<html xmlns=quot;http://www.w3.org/1999/XHTMLquot; xml:lang=quot;enquot; lang=quot;enquot;>
<head>
<title>Page Title</title>
<meta http-equiv=quot;content-typequot; content=quot;text/html; charset=utf-8quot; />
<meta http-equiv=quot;Content-Languagequot; content=quot;en-usquot; />
</head>
<body>
<h1>This is a heading</h1>
<p>This is a paragraph with a <a href=quot;http://easy-reader.netquot;>link</a></p>
<ul>
<li>a list item</li>
<li>another list item</li>
<li>a third list item</li>
</ul>
</body>
</html>
IN CONTROL 2009 5
15. FUNDAMENTAL JAVASCRIPT
Getters
๏ document.getElementById( ID );
๏ document.getElementsByTagName( tagName );
๏ element.getAttribute( attributeName );
IN CONTROL 2009 9
16. FUNDAMENTAL JAVASCRIPT
Using getters
๏ var content = document.getElementById( 'content' );
๏ var abbrs = document.getElementsByTagName( 'abbr' );
๏ var title = abbrs[0].getAttribute( 'title' );
IN CONTROL 2009 10
17. FUNDAMENTAL JAVASCRIPT
Language comparison
๏ English
Get the element with the ID “content”.
๏ CSS
#content { }
๏ DOM
document.getElementById( 'content' )
IN CONTROL 2009 11
18. FUNDAMENTAL JAVASCRIPT
Language comparison
๏ English
Get all the paragraphs in a document.
๏ CSS
p { }
๏ DOM
document.getElementsByTagName( 'p' );
IN CONTROL 2009 12
19. FUNDAMENTAL JAVASCRIPT
Language comparison
๏ English
Get all the paragraphs within the element with the ID
“content”.
๏ CSS
#content p { }
๏ DOM
document.getElementById( 'content' )
.getElementsByTagName( 'p' );
IN CONTROL 2009 13
20. FUNDAMENTAL JAVASCRIPT
Content generation
๏ Bad:
‣ document.write();
‣ innerHTML
IN CONTROL 2009 14
21. FUNDAMENTAL JAVASCRIPT
Content generation
๏ Good:
‣ document.createElement( tagName );
‣ document.createTextNode( text );
‣ element.setAttribute( name, value );
IN CONTROL 2009 15
22. FUNDAMENTAL JAVASCRIPT
Generation in action
๏ var abbr = document.createElement( 'abbr' );
๏ var text = document.createTextNode( 'TN' );
๏ abbr.setAttribute( 'title', 'Tennessee' );
IN CONTROL 2009 16
23. FUNDAMENTAL JAVASCRIPT
Adding to the DOM
๏ element.appendChild( newNode );
๏ element.insertBefore( newNode, targetNode );
IN CONTROL 2009 17
24. FUNDAMENTAL JAVASCRIPT
Adding to the DOM
var abbr = document.createElement( 'abbr' );
var text = document.createTextNode( 'TN' );
abbr.setAttribute( 'title', 'Tennessee' );
abbr.appendChild( text );
var p = document.getElementsByTagName( 'p' )[0];
p.appendChild( abbr );
IN CONTROL 2009 18
27. FUNDAMENTAL JAVASCRIPT
The document
<!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Strict//ENquot;
quot;http://www.w3.org/TR/XHTML1/DTD/XHTML1-strict.dtdquot;>
<html xmlns=quot;http://www.w3.org/1999/XHTMLquot; xml:lang=quot;enquot; lang=quot;enquot;>
<head>
<title>Example 1</title>
<meta http-equiv=quot;content-typequot; content=quot;text/html; charset=utf-8quot; />
<meta http-equiv=quot;Content-Languagequot; content=quot;en-usquot; />
</head>
<body>
<blockquote cite=quot;http://en.wikipedia.org/wiki/Progressive_Enhancementquot;>
<p>Progressive Enhancement, as a label for a strategy for Web design,
was coined by Steven Champeon in a series of articles and presentations
for Webmonkey and the SxSW Interactive conference.</p>
</blockquote>
</body>
</html>
IN CONTROL 2009 21
28. FUNDAMENTAL JAVASCRIPT
The page
Progressive Enhancement, as a label for a
strategy for Web design, was coined by
Steven Champeon in a series of articles
and presentations for Webmonkey and
the SxSW Interactive conference.
IN CONTROL 2009 22
29. FUNDAMENTAL JAVASCRIPT
The document
<!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Strict//ENquot;
quot;http://www.w3.org/TR/XHTML1/DTD/XHTML1-strict.dtdquot;>
<html xmlns=quot;http://www.w3.org/1999/XHTMLquot; xml:lang=quot;enquot; lang=quot;enquot;>
<head>
<title>Example 1</title>
<meta http-equiv=quot;content-typequot; content=quot;text/html; charset=utf-8quot; />
<meta http-equiv=quot;Content-Languagequot; content=quot;en-usquot; />
</head>
<body>
<blockquote cite=quot;http://en.wikipedia.org/wiki/Progressive_Enhancementquot;>
<p>Progressive Enhancement, as a label for a strategy for Web design,
was coined by Steven Champeon in a series of articles and presentations
for Webmonkey and the SxSW Interactive conference.</p>
</blockquote>
</body>
</html>
IN CONTROL 2009 23
30. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document
2. Get the value of the cite attribute
3. Create a new anchor element node
4. Set the href attribute of the anchor
5. Create a new text node with the word “source”
6. Insert the text into the anchor
7. Insert the anchor into the blockquote.
IN CONTROL 2009 24
31. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document
2. Get the value of the cite attribute
3. Create a new anchor element node
4. Set the href attribute of the anchor
5. Create a new text node with the word “source”
6. Insert the text into the anchor
7. Insert the anchor into the blockquote.
IN CONTROL 2009 25
32. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document getElementsByTagName
2. Get the value of the cite attribute
3. Create a new anchor element node
4. Set the href attribute of the anchor
5. Create a new text node with the word “source”
6. Insert the text into the anchor
7. Insert the anchor into the blockquote.
IN CONTROL 2009 25
33. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document getElementsByTagName
2. Get the value of the cite attribute getAttribute
3. Create a new anchor element node
4. Set the href attribute of the anchor
5. Create a new text node with the word “source”
6. Insert the text into the anchor
7. Insert the anchor into the blockquote.
IN CONTROL 2009 25
34. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document getElementsByTagName
2. Get the value of the cite attribute getAttribute
3. Create a new anchor element node createElement
4. Set the href attribute of the anchor
5. Create a new text node with the word “source”
6. Insert the text into the anchor
7. Insert the anchor into the blockquote.
IN CONTROL 2009 25
35. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document getElementsByTagName
2. Get the value of the cite attribute getAttribute
3. Create a new anchor element node createElement
4. Set the href attribute of the anchor setAttribute
5. Create a new text node with the word “source”
6. Insert the text into the anchor
7. Insert the anchor into the blockquote.
IN CONTROL 2009 25
36. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document getElementsByTagName
2. Get the value of the cite attribute getAttribute
3. Create a new anchor element node createElement
4. Set the href attribute of the anchor setAttribute
5. Create a new text node with the word “source” createTextNode
6. Insert the text into the anchor
7. Insert the anchor into the blockquote.
IN CONTROL 2009 25
37. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document getElementsByTagName
2. Get the value of the cite attribute getAttribute
3. Create a new anchor element node createElement
4. Set the href attribute of the anchor setAttribute
5. Create a new text node with the word “source” createTextNode
6. Insert the text into the anchor appendChild
7. Insert the anchor into the blockquote.
IN CONTROL 2009 25
38. FUNDAMENTAL JAVASCRIPT
The idea
1. Find all the blockquotes in a document getElementsByTagName
2. Get the value of the cite attribute getAttribute
3. Create a new anchor element node createElement
4. Set the href attribute of the anchor setAttribute
5. Create a new text node with the word “source” createTextNode
6. Insert the text into the anchor appendChild
7. Insert the anchor into the blockquote. appendChild
IN CONTROL 2009 25
39. FUNDAMENTAL JAVASCRIPT
The code
var quotes = document.getElementsByTagName( 'blockquote' );
for( var i=0; i < quotes.length; i++ ){
var source = quotes[i].getAttribute( 'cite' );
if( source ){
var link = document.createElement( 'a' );
link.setAttribute( 'href', source );
var text = document.createTextNode( 'source' );
link.appendChild( text );
quotes[i].appendChild( link );
}
}
IN CONTROL 2009 26
40. FUNDAMENTAL JAVASCRIPT
The code
var quotes = document.getElementsByTagName( 'blockquote' );
for( var i=0; i < quotes.length; i++ ){
var source = quotes[i].getAttribute( 'cite' );
if( source ){
var link = document.createElement( 'a' );
link.setAttribute( 'href', source );
var text = document.createTextNode( 'source' );
link.appendChild( text );
var para = document.createElement( 'p' );
para.className = 'attribution';
para.appendChild( link );
quotes[i].appendChild( para );
}
}
IN CONTROL 2009 27
41. FUNDAMENTAL JAVASCRIPT
The code
function sourceQuotes(){
var quotes = document.getElementsByTagName( 'blockquote' );
for( var i=0; i < quotes.length; i++ ){
var source = quotes[i].getAttribute( 'cite' );
if( source ){
var link = document.createElement( 'a' );
link.setAttribute( 'href', source );
var text = document.createTextNode( 'source' );
link.appendChild( text );
var para = document.createElement( 'p' );
para.className = 'attribution';
para.appendChild( link );
quotes[i].appendChild( para );
}
}
}
window.onload = sourceQuotes;
IN CONTROL 2009 28
42. FUNDAMENTAL JAVASCRIPT
The result
Progressive Enhancement, as a label for a
strategy for Web design, was coined by
Steven Champeon in a series of articles
and presentations for Webmonkey and
the SxSW Interactive conference.
IN CONTROL 2009 29
43. FUNDAMENTAL JAVASCRIPT
The result
Progressive Enhancement, as a label for a
strategy for Web design, was coined by
Steven Champeon in a series of articles
and presentations for Webmonkey and
the SxSW Interactive conference.
source
IN CONTROL 2009 30
48. FUNDAMENTAL JAVASCRIPT
Graceful Degradation
๏ A holdover from engineering
๏ Build for the latest browsers
๏ Test on older devices
‣ Happens at the end
‣ Accounts for few versions
๏ Expects a poor experience for older browsers
๏ Fixes major issues but little else
IN CONTROL 2009 34
72. FUNDAMENTAL JAVASCRIPT
Rich, chocolaty goodness
๏ some browsers only handle
a certain level of CSS
๏ some companies turn off
JavaScript
IN CONTROL 2009 52
75. FUNDAMENTAL JAVASCRIPT
The candy coating
๏ JavaScript can turn a website
into an experience
IN CONTROL 2009 54
76. FUNDAMENTAL JAVASCRIPT
The candy coating
๏ JavaScript can turn a website
into an experience
๏ we can deliver our scripts
a la carte
IN CONTROL 2009 54
99. FUNDAMENTAL JAVASCRIPT
Don’t do this
<a href=quot;javascript:someFunction();quot;>some text</a>
or
<a href=quot;javascript:void(null);quot;
onclick=quot;someFunction();quot;>some text</a>
or
<a href=quot;#quot; onclick=quot;someFunction();quot;>some text</a>
IN CONTROL 2009 67
100. FUNDAMENTAL JAVASCRIPT
An improvement, but still...
<a href=quot;http://offsite.comquot;
onclick=quot;newWin( this.href ); return false;quot;>
some text</a>
IN CONTROL 2009 68
101. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
102. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
103. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
104. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
105. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
106. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
107. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
108. FUNDAMENTAL JAVASCRIPT
Getting warmer...
window.onload = handleExternalLinks;
function handleExternalLinks(){
var server = document.location.hostname;
var anchors = document.getElementsByTagName(quot;aquot;);
var i, href;
for( i=0; i < anchors.length; i++ ){
href = anchors[i].href;
if( href.indexOf(quot;http://quot; + server) == -1 &&
href.indexOf(quot;https://quot; + server) == -1 ){
// HREF is not a file on my server
anchors[i].onclick = function(){
newWin( this.href );
};
}
}
}
IN CONTROL 2009 69
109. FUNDAMENTAL JAVASCRIPT
You’re hot
document.getElementsByTagName( 'body' )[0]
.onclick = clickDelegator;
function clickDelegator( e ){
e = ( e ) ? e : event;
var el = e.target || e.srcElement;
// external links
if( el.nodeName.toLowerCase() == 'a' &&
el.getAttribute( 'rel' ) == 'external' ){
newWin( el.href );
}
}
IN CONTROL 2009 70
110. FUNDAMENTAL JAVASCRIPT
You’re hot
document.getElementsByTagName( 'body' )[0]
.onclick = clickDelegator;
function clickDelegator( e ){
e = ( e ) ? e : event;
var el = e.target || e.srcElement;
// external links
if( el.nodeName.toLowerCase() == 'a' &&
el.getAttribute( 'rel' ) == 'external' ){
newWin( el.href );
}
}
IN CONTROL 2009 70
111. FUNDAMENTAL JAVASCRIPT
You’re hot
document.getElementsByTagName( 'body' )[0]
.onclick = clickDelegator;
function clickDelegator( e ){
e = ( e ) ? e : event;
var el = e.target || e.srcElement;
// external links
if( el.nodeName.toLowerCase() == 'a' &&
el.getAttribute( 'rel' ) == 'external' ){
newWin( el.href );
}
}
IN CONTROL 2009 70
112. FUNDAMENTAL JAVASCRIPT
You’re hot
document.getElementsByTagName( 'body' )[0]
.onclick = clickDelegator;
function clickDelegator( e ){
e = ( e ) ? e : event;
var el = e.target || e.srcElement;
// external links
if( el.nodeName.toLowerCase() == 'a' &&
el.getAttribute( 'rel' ) == 'external' ){
newWin( el.href );
}
}
IN CONTROL 2009 70
113. FUNDAMENTAL JAVASCRIPT
You’re hot
document.getElementsByTagName( 'body' )[0]
.onclick = clickDelegator;
function clickDelegator( e ){
e = ( e ) ? e : event;
var el = e.target || e.srcElement;
// external links
if( el.nodeName.toLowerCase() == 'a' &&
el.getAttribute( 'rel' ) == 'external' ){
newWin( el.href );
}
}
IN CONTROL 2009 70
114. FUNDAMENTAL JAVASCRIPT
You’re hot
document.getElementsByTagName( 'body' )[0]
.onclick = clickDelegator;
function clickDelegator( e ){
e = ( e ) ? e : event;
var el = e.target || e.srcElement;
// external links
if( el.nodeName.toLowerCase() == 'a' &&
el.getAttribute( 'rel' ) == 'external' ){
newWin( el.href );
}
}
IN CONTROL 2009 70
119. FUNDAMENTAL JAVASCRIPT
Remember stuff like this?
<a href=quot;foo.htmlquot;
style=quot;color:blue;quot;
onmouseover=quot;this.style.color='red'quot;
onmouseout=quot;this.style.color='blue'quot;>Foo</a>
IN CONTROL 2009 73
120. FUNDAMENTAL JAVASCRIPT
Remember stuff like this?
<a href=quot;foo.htmlquot;
style=quot;color:blue;quot;
onmouseover=quot;this.style.color='red'quot;
onmouseout=quot;this.style.color='blue'quot;>Foo</a>
Obvisouly, we should be doing this instead:
a, a:link, a:visited {
color: blue;
}
a:hover {
color: red;
}
IN CONTROL 2009 73
121. FUNDAMENTAL JAVASCRIPT
Isn’t this the same?
for( i=0; i<objects.length; i++){
objects[i].style.display = 'none';
}
IN CONTROL 2009 74
124. FUNDAMENTAL JAVASCRIPT
Maintenance options
๏ external style rules added to your CSS file (by hand)
๏ external CSS file added to the document (by hand)
๏ external CSS file added to the document via script
๏ embedding CSS in the document via script
IN CONTROL 2009 77
125. FUNDAMENTAL JAVASCRIPT
Option 1: Add by hand
At the end of your screen layout CSS file:
/* =START WickedCool Script CSS (do not remove) */
.wicked {
color: red;
font: bold 4em/2 quot;Comic Sansquot;;
}
.cool {
color: blue;
font: bold 4em/2 quot;Comic Sansquot;;
}
/* =END WickedCool Script CSS */
IN CONTROL 2009 78
126. FUNDAMENTAL JAVASCRIPT
Option 2: Include by hand
Added to the head of your document:
<script type=quot;text/javascriptquot; src=quot;WickedCool.jsquot;></script>
<link rel=quot;stylesheetquot; type=quot;text/cssquot;
media=quot;screenquot; href=quot;WickedCool.cssquot; />
IN CONTROL 2009 79
127. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
128. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
129. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
130. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
131. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
132. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
133. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
134. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
function FindPath( filename ){
var path = false;
var scripts = document.getElementsByTagName( 'script' );
for( var i=0; i<scripts.length; i++ ){
if( scripts[i].getAttribute( 'src' ) &&
scripts[i].getAttribute( 'src' )
.indexOf( filename ) != -1 ){
path = scripts[i].getAttribute( 'src' )
.replace( new RegExp( filename ), '' );
break;
}
}
return path;
}
IN CONTROL 2009 80
135. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
var WickedCool = {
jsFile: 'WickedCool.js',
cssFile: 'WickedCool.css',
basePath: false,
initialize: function(){
// determine the path
this.basePath = FindPath( this.jsFile );
// add the CSS file
var css = document.createElement( 'link' );
css.setAttribute( 'rel', 'stylesheet' );
css.setAttribute( 'type', 'text/css' );
css.setAttribute( 'media', 'screen' );
css.setAttribute( 'href', this.basePath + this.cssFile );
document.getElementsByTagName( 'head' )[0]
.appendChild( css );
// do the rest of the wicked cool stuff
}
};
IN CONTROL 2009 81
136. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
var WickedCool = {
jsFile: 'WickedCool.js',
cssFile: 'WickedCool.css',
basePath: false,
initialize: function(){
// determine the path
this.basePath = FindPath( this.jsFile );
// add the CSS file
var css = document.createElement( 'link' );
css.setAttribute( 'rel', 'stylesheet' );
css.setAttribute( 'type', 'text/css' );
css.setAttribute( 'media', 'screen' );
css.setAttribute( 'href', this.basePath + this.cssFile );
document.getElementsByTagName( 'head' )[0]
.appendChild( css );
// do the rest of the wicked cool stuff
}
};
IN CONTROL 2009 81
137. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
var WickedCool = {
jsFile: 'WickedCool.js',
cssFile: 'WickedCool.css',
basePath: false,
initialize: function(){
// determine the path
this.basePath = FindPath( this.jsFile );
// add the CSS file
var css = document.createElement( 'link' );
css.setAttribute( 'rel', 'stylesheet' );
css.setAttribute( 'type', 'text/css' );
css.setAttribute( 'media', 'screen' );
css.setAttribute( 'href', this.basePath + this.cssFile );
document.getElementsByTagName( 'head' )[0]
.appendChild( css );
// do the rest of the wicked cool stuff
}
};
IN CONTROL 2009 81
138. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
var WickedCool = {
jsFile: 'WickedCool.js',
cssFile: 'WickedCool.css',
basePath: false,
initialize: function(){
// determine the path
this.basePath = FindPath( this.jsFile );
// add the CSS file
var css = document.createElement( 'link' );
css.setAttribute( 'rel', 'stylesheet' );
css.setAttribute( 'type', 'text/css' );
css.setAttribute( 'media', 'screen' );
css.setAttribute( 'href', this.basePath + this.cssFile );
document.getElementsByTagName( 'head' )[0]
.appendChild( css );
// do the rest of the wicked cool stuff
}
};
IN CONTROL 2009 81
139. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
var WickedCool = {
jsFile: 'WickedCool.js',
cssFile: 'WickedCool.css',
basePath: false,
initialize: function(){
// determine the path
this.basePath = FindPath( this.jsFile );
// add the CSS file
var css = document.createElement( 'link' );
css.setAttribute( 'rel', 'stylesheet' );
css.setAttribute( 'type', 'text/css' );
css.setAttribute( 'media', 'screen' );
css.setAttribute( 'href', this.basePath + this.cssFile );
document.getElementsByTagName( 'head' )[0]
.appendChild( css );
// do the rest of the wicked cool stuff
}
};
IN CONTROL 2009 81
140. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
var WickedCool = {
jsFile: 'WickedCool.js',
cssFile: 'WickedCool.css',
basePath: false,
initialize: function(){
// determine the path
this.basePath = FindPath( this.jsFile );
// add the CSS file
var css = document.createElement( 'link' );
css.setAttribute( 'rel', 'stylesheet' );
css.setAttribute( 'type', 'text/css' );
css.setAttribute( 'media', 'screen' );
css.setAttribute( 'href', this.basePath + this.cssFile );
document.getElementsByTagName( 'head' )[0]
.appendChild( css );
// do the rest of the wicked cool stuff
}
};
IN CONTROL 2009 81
141. FUNDAMENTAL JAVASCRIPT
Option 3: Scripted include
var WickedCool = {
jsFile: 'WickedCool.js',
cssFile: 'WickedCool.css',
basePath: false,
initialize: function(){
// determine the path
this.basePath = FindPath( this.jsFile );
// add the CSS file
var css = document.createElement( 'link' );
css.setAttribute( 'rel', 'stylesheet' );
css.setAttribute( 'type', 'text/css' );
css.setAttribute( 'media', 'screen' );
css.setAttribute( 'href', this.basePath + this.cssFile );
document.getElementsByTagName( 'head' )[0]
.appendChild( css );
// do the rest of the wicked cool stuff
}
};
IN CONTROL 2009 81
142. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
function addCSS( styles ){
var el = document.createElement( 'style' );
el.setAttribute( 'type', 'text/css' );
if( el.styleSheet ){
el.styleSheet.cssText = styles;
} else {
el.appendChild( document.createTextNode( styles ) );
}
document.getElementsByTagName( 'head' )[0]
.appendChild( el );
}
based on the work of Nicholas Zakas
IN CONTROL 2009 82
143. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
function addCSS( styles ){
var el = document.createElement( 'style' );
el.setAttribute( 'type', 'text/css' );
if( el.styleSheet ){
el.styleSheet.cssText = styles;
} else {
el.appendChild( document.createTextNode( styles ) );
}
document.getElementsByTagName( 'head' )[0]
.appendChild( el );
}
based on the work of Nicholas Zakas
IN CONTROL 2009 82
144. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
function addCSS( styles ){
var el = document.createElement( 'style' );
el.setAttribute( 'type', 'text/css' );
if( el.styleSheet ){
el.styleSheet.cssText = styles;
} else {
el.appendChild( document.createTextNode( styles ) );
}
document.getElementsByTagName( 'head' )[0]
.appendChild( el );
}
based on the work of Nicholas Zakas
IN CONTROL 2009 82
145. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
function addCSS( styles ){
var el = document.createElement( 'style' );
el.setAttribute( 'type', 'text/css' );
if( el.styleSheet ){
el.styleSheet.cssText = styles;
} else {
el.appendChild( document.createTextNode( styles ) );
}
document.getElementsByTagName( 'head' )[0]
.appendChild( el );
}
based on the work of Nicholas Zakas
IN CONTROL 2009 82
146. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
function addCSS( styles ){
var el = document.createElement( 'style' );
el.setAttribute( 'type', 'text/css' );
if( el.styleSheet ){
el.styleSheet.cssText = styles;
} else {
el.appendChild( document.createTextNode( styles ) );
}
document.getElementsByTagName( 'head' )[0]
.appendChild( el );
}
based on the work of Nicholas Zakas
IN CONTROL 2009 82
147. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
function addCSS( styles ){
var el = document.createElement( 'style' );
el.setAttribute( 'type', 'text/css' );
if( el.styleSheet ){
el.styleSheet.cssText = styles;
} else {
el.appendChild( document.createTextNode( styles ) );
}
document.getElementsByTagName( 'head' )[0]
.appendChild( el );
}
based on the work of Nicholas Zakas
IN CONTROL 2009 82
148. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
var WickedCool = {
_css: '.wicked { color: red; ' +
' font: bold 4em/2 quot;Comic Sansquot;; } ' +
'.cool { color: blue; ' +
' font: bold 4em/2' quot;Comic Sansquot;; }',
initialize: function(){
// add the CSS
addCSS( this._css );
// do the rest of the wicked cool stuff
}
};
based on the work of Nicholas Zakas
IN CONTROL 2009 83
149. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
var WickedCool = {
_css: '.wicked { color: red; ' +
' font: bold 4em/2 quot;Comic Sansquot;; } ' +
'.cool { color: blue; ' +
' font: bold 4em/2' quot;Comic Sansquot;; }',
initialize: function(){
// add the CSS
addCSS( this._css );
// do the rest of the wicked cool stuff
}
};
based on the work of Nicholas Zakas
IN CONTROL 2009 83
150. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
var WickedCool = {
_css: '.wicked { color: red; ' +
' font: bold 4em/2 quot;Comic Sansquot;; } ' +
'.cool { color: blue; ' +
' font: bold 4em/2' quot;Comic Sansquot;; }',
initialize: function(){
// add the CSS
addCSS( this._css );
// do the rest of the wicked cool stuff
}
};
based on the work of Nicholas Zakas
IN CONTROL 2009 83
151. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
var WickedCool = {
_css: '.wicked { color: red; ' +
' font: bold 4em/2 quot;Comic Sansquot;; } ' +
'.cool { color: blue; ' +
' font: bold 4em/2' quot;Comic Sansquot;; }',
initialize: function(){
// add the CSS
addCSS( this._css );
// do the rest of the wicked cool stuff
}
};
based on the work of Nicholas Zakas
IN CONTROL 2009 83
152. FUNDAMENTAL JAVASCRIPT
Option 4: Scripted embed
var WickedCool = {
_css: '.wicked { color: red; ' +
' font: bold 4em/2 quot;Comic Sansquot;; } ' +
'.cool { color: blue; ' +
' font: bold 4em/2' quot;Comic Sansquot;; }',
initialize: function(){
// add the CSS
addCSS( this._css );
// do the rest of the wicked cool stuff
}
};
based on the work of Nicholas Zakas
IN CONTROL 2009 83
156. FUNDAMENTAL JAVASCRIPT
How do we do that?
๏ make your style rules specific:
.TabInterface-folder {
...
}
or
#TabInterface .tab {
...
}
#TabInterface .tab.active {
...
}
IN CONTROL 2009 85
157. FUNDAMENTAL JAVASCRIPT
How do we do that?
<div id=quot;mainquot; class=quot;tabbedquot;>
becomes
<div id=quot;mainquot; class=quot;tabbed-onquot;>
IN CONTROL 2009 86
158. FUNDAMENTAL JAVASCRIPT
How do we do that?
Default Activated
add “-on” to the class .tabbed .tabbed-on
add an activation class .auto-submit .auto-submit.active
change the form of the class .replace-me .replaced
IN CONTROL 2009 86
160. FUNDAMENTAL JAVASCRIPT
Look for methods
function someFunction(){
if( !document.getElementsByTagName ) return;
// code that uses document.getElementsByTagName()
...
}
IN CONTROL 2009 88
161. FUNDAMENTAL JAVASCRIPT
Look for methods
function someFunction(){
if( !document.getElementsByTagName ||
!document.getElementById ) return;
/* code that uses document.getElementsByTagName()
and document.getElementById() */
}
IN CONTROL 2009 89
162. FUNDAMENTAL JAVASCRIPT
Look for elements
function someFunction(){
if( !document.getElementsByTagName ||
!document.getElementsByTagName( 'p' ) ) return;
/* code that uses document.getElementsByTagName()
and requires the presence of a P element */
...
}
IN CONTROL 2009 90
163. FUNDAMENTAL JAVASCRIPT
Look for identified elements
function someFunction(){
if( !document.getElementById ||
!document.getElementById( 'content' ) ) return;
// code that requires the presence of #content
...
}
IN CONTROL 2009 91
164. FUNDAMENTAL JAVASCRIPT
Look for objects
function someFunction(){
if( typeof( Prototype ) == 'undefined' ) return;
// code that uses Prototype
...
}
IN CONTROL 2009 92
165. FUNDAMENTAL JAVASCRIPT
Look for object versions
function someFunction(){
if( typeof( jQuery ) == 'undefined' ||
parseFloat( jQuery.jquery ) < 1.2 ) return;
// code that uses jQuery 1.2 or higher
...
}
IN CONTROL 2009 93
166. FUNDAMENTAL JAVASCRIPT
Look before you leap
window.onload = function(){
if( document.getElementsByTagName &&
document.getElementById ){
someFunction();
}
};
IN CONTROL 2009 94
167. FUNDAMENTAL JAVASCRIPT
PE with JavaScript
๏ Start with the content, then work your way out
๏ Get unobtrusive
๏ Keep some distance between your styles & your scripts
๏ Always wear your detective hat
IN CONTROL 2009 95
170. FUNDAMENTAL JAVASCRIPT
Traditional approach
<h1>Pumpkin Pie</h1>
<div class=quot;containerquot;>
<div class=quot;sectionquot;>
<h2>Overview</h2>
<img src=quot;pie.jpgquot; alt=quot;quot;>
<p>Whether you're hosting a festive party or a casual get-together with
friends, our Pumpkin Pie will make entertaining easy!</p>
...
</div>
...
<ul class=quot;tabsquot;>
<li><a href=quot;#quot;>Overview</a></li>
<li><a href=quot;#quot;>Ingredients</a></li>
<li><a href=quot;#quot;>Directions</a></li>
<li><a href=quot;#quot;>Nutrition</a></li>
</ul>
</div>
IN CONTROL 2009 98
171. FUNDAMENTAL JAVASCRIPT
Traditional approach
<h1>Pumpkin Pie</h1>
<div class=quot;containerquot;>
<div class=quot;sectionquot;>
<h2>Overview</h2>
<img src=quot;pie.jpgquot; alt=quot;quot;>
<p>Whether you're hosting a festive party or a casual get-together with
friends, our Pumpkin Pie will make entertaining easy!</p>
...
</div>
...
<ul class=quot;tabsquot;>
<li><a href=quot;#quot;>Overview</a></li>
<li><a href=quot;#quot;>Ingredients</a></li>
<li><a href=quot;#quot;>Directions</a></li>
<li><a href=quot;#quot;>Nutrition</a></li>
</ul>
</div>
IN CONTROL 2009 98
172. FUNDAMENTAL JAVASCRIPT
Traditional approach
<h1>Pumpkin Pie</h1>
<div class=quot;containerquot;>
<div class=quot;sectionquot;>
<h2>Overview</h2>
<img src=quot;pie.jpgquot; alt=quot;quot;>
<p>Whether you're hosting a festive party or a casual get-together with
friends, our Pumpkin Pie will make entertaining easy!</p>
...
</div>
...
<ul class=quot;tabsquot;>
<li><a href=quot;#quot;>Overview</a></li>
<li><a href=quot;#quot;>Ingredients</a></li>
<li><a href=quot;#quot;>Directions</a></li>
<li><a href=quot;#quot;>Nutrition</a></li>
</ul>
</div>
IN CONTROL 2009 98
173. FUNDAMENTAL JAVASCRIPT
Traditional approach
<h1>Pumpkin Pie</h1>
<div class=quot;containerquot;>
<div class=quot;sectionquot;>
<h2>Overview</h2>
<img src=quot;pie.jpgquot; alt=quot;quot;>
<p>Whether you're hosting a festive party or a casual get-together with
friends, our Pumpkin Pie will make entertaining easy!</p>
...
</div>
...
<ul class=quot;tabsquot;>
<li><a href=quot;#quot;>Overview</a></li>
<li><a href=quot;#quot;>Ingredients</a></li>
<li><a href=quot;#quot;>Directions</a></li>
<li><a href=quot;#quot;>Nutrition</a></li>
</ul>
</div>
IN CONTROL 2009 98
179. FUNDAMENTAL JAVASCRIPT
The actual source
<h1>Pumpkin Pie</h1>
<div class=quot;tabbedquot;>
<h2>Overview</h2>
<img src=quot;pie.jpgquot; alt=quot;quot; />
<p>Whether you're hosting a festive party or a casual get-together with friends,
our Pumpkin Pie will make entertaining easy!</p>
...
<h2>Ingredients</h2>
<ul>
<li>1 (9<abbr title=quot;inchquot;>in</abbr>) unbaked deep dish pie crust</li>
<li>½ cup white sugar</li>
<li>1 <abbr title=quot;teaspoonquot;>tsp</abbr> ground cinnamon</li>
...
</ul>
<h2>Directions</h2>
...
</div>
IN CONTROL 2009 103
180. FUNDAMENTAL JAVASCRIPT
The actual source
<h1>Pumpkin Pie</h1>
<div class=quot;tabbedquot;>
<h2>Overview</h2>
<img src=quot;pie.jpgquot; alt=quot;quot; />
<p>Whether you're hosting a festive party or a casual get-together with friends,
our Pumpkin Pie will make entertaining easy!</p>
...
<h2>Ingredients</h2>
<ul>
<li>1 (9<abbr title=quot;inchquot;>in</abbr>) unbaked deep dish pie crust</li>
<li>½ cup white sugar</li>
<li>1 <abbr title=quot;teaspoonquot;>tsp</abbr> ground cinnamon</li>
...
</ul>
<h2>Directions</h2>
...
</div>
IN CONTROL 2009 103
182. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
// Public Properties
this.Version = '0.3'; // version
// Private Properties
var _i = i; // incrementor
var _cabinet = el; // the quot;cabinetquot; element (container)
var _id = false; // ID of _cabinet
var _active = false; // ID of the active quot;folderquot;
var _tag = false; // tag we'll split it on
// the tab list
var _index = document.createElement( 'ul' );
// prototype elements
var _els = { li: document.createElement( 'li' ),
div: document.createElement( 'div' ) };
// methods to go here
};
IN CONTROL 2009 105
183. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
// Public Properties
this.Version = '0.3'; // version
// Private Properties
var _i = i; // incrementor
var _cabinet = el; // the quot;cabinetquot; element (container)
var _id = false; // ID of _cabinet
var _active = false; // ID of the active quot;folderquot;
var _tag = false; // tag we'll split it on
// the tab list
var _index = document.createElement( 'ul' );
// prototype elements
var _els = { li: document.createElement( 'li' ),
div: document.createElement( 'div' ) };
// methods to go here
};
IN CONTROL 2009 105
184. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
// Public Properties
this.Version = '0.3'; // version
// Private Properties
var _i = i; // incrementor
var _cabinet = el; // the quot;cabinetquot; element (container)
var _id = false; // ID of _cabinet
var _active = false; // ID of the active quot;folderquot;
var _tag = false; // tag we'll split it on
// the tab list
var _index = document.createElement( 'ul' );
// prototype elements
var _els = { li: document.createElement( 'li' ),
div: document.createElement( 'div' ) };
// methods to go here
};
IN CONTROL 2009 105
185. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
// Public Properties
this.Version = '0.3'; // version
// Private Properties
var _i = i; // incrementor
var _cabinet = el; // the quot;cabinetquot; element (container)
var _id = false; // ID of _cabinet
var _active = false; // ID of the active quot;folderquot;
var _tag = false; // tag we'll split it on
// the tab list
var _index = document.createElement( 'ul' );
// prototype elements
var _els = { li: document.createElement( 'li' ),
div: document.createElement( 'div' ) };
// methods to go here
};
IN CONTROL 2009 105
186. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
// Public Properties
this.Version = '0.3'; // version
// Private Properties
var _i = i; // incrementor
var _cabinet = el; // the quot;cabinetquot; element (container)
var _id = false; // ID of _cabinet
var _active = false; // ID of the active quot;folderquot;
var _tag = false; // tag we'll split it on
// the tab list
var _index = document.createElement( 'ul' );
// prototype elements
var _els = { li: document.createElement( 'li' ),
div: document.createElement( 'div' ) };
// methods to go here
};
IN CONTROL 2009 105
187. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function initialize(){
// code to come
}
function addClassName( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
}
function removeClassName( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
}
// start it up
initialize();
};
IN CONTROL 2009 106
188. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function initialize(){
// code to come
}
function addClassName( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
}
function removeClassName( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
}
// start it up
initialize();
};
IN CONTROL 2009 106
189. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function initialize(){
// code to come
}
function addClassName( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
}
function removeClassName( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
}
// start it up
initialize();
};
IN CONTROL 2009 106
190. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function initialize(){
// code to come
}
function addClassName( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
}
function removeClassName( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
}
// start it up
initialize();
};
IN CONTROL 2009 106
191. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function initialize(){
// code to come
}
function addClassName( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
}
function removeClassName( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
}
// start it up
initialize();
};
IN CONTROL 2009 106
192. FUNDAMENTAL JAVASCRIPT
THE CODE
function TabInterface( el, i ){
function initialize(){
// set the id
_id = el.getAttribute( 'id' ) || 'folder-' + _i;
if( !el.getAttribute( 'id' ) ) el.setAttribute( 'id', _id );
// trim whitespace
var node = _cabinet.firstChild;
while( node ){
var nextNode = node.nextSibling;
if( node.nodeType == 3 &&
!/S/.test( node.nodeValue ) )
_cabinet.removeChild( node );
node = nextNode;
}
}
...
};
IN CONTROL 2009 107
193. FUNDAMENTAL JAVASCRIPT
THE CODE
function TabInterface( el, i ){
function initialize(){
// set the id
_id = el.getAttribute( 'id' ) || 'folder-' + _i;
if( !el.getAttribute( 'id' ) ) el.setAttribute( 'id', _id );
// trim whitespace
var node = _cabinet.firstChild;
while( node ){
var nextNode = node.nextSibling;
if( node.nodeType == 3 &&
!/S/.test( node.nodeValue ) )
_cabinet.removeChild( node );
node = nextNode;
}
}
...
};
IN CONTROL 2009 107
194. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
// find the first heading
var headers = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ];
var hLen = headers.length;
for( var i=0; i<hLen; i++ ){
if( _cabinet.firstChild.nodeName.toLowerCase() == headers[i] ){
_tag = headers[i];
break;
}
}
}
...
};
IN CONTROL 2009 108
195. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
// establish the folders
var rexp = new RegExp( '<(' + _tag + ')', 'ig' );
var arr = _cabinet.innerHTML.replace( rexp, quot;||||<$1quot; ).split( '||||' );
arr.shift();
_cabinet.innerHTML = '';
removeClassName( _cabinet, 'tabbed' );
addClassName( _cabinet, 'tabbed-on' );
}
...
};
IN CONTROL 2009 109
196. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
// build the div
var folder = _els.div.cloneNode( true );
addClassName( folder, 'folder' );
folder.setAttribute( 'id', _id + '-' + k );
folder.innerHTML = arr[k];
_cabinet.appendChild( folder );
// build the tab
var tab = _els.li.cloneNode( true );
tab.folder = folder.getAttribute( 'id' );
tab.setAttribute( 'id', tab.folder + '-tab' );
tab.onclick = swap; // set the action
var heading = folder.getElementsByTagName( _tag )[0];
tab.innerHTML = heading.innerHTML;
addClassName( heading, 'hidden' );
_index.appendChild( tab );
}
}
...
IN CONTROL 2009 110
197. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
// build the div
var folder = _els.div.cloneNode( true );
addClassName( folder, 'folder' );
folder.setAttribute( 'id', _id + '-' + k );
folder.innerHTML = arr[k];
_cabinet.appendChild( folder );
// build the tab
var tab = _els.li.cloneNode( true );
tab.folder = folder.getAttribute( 'id' );
tab.setAttribute( 'id', tab.folder + '-tab' );
tab.onclick = swap; // set the action
var heading = folder.getElementsByTagName( _tag )[0];
tab.innerHTML = heading.innerHTML;
addClassName( heading, 'hidden' );
_index.appendChild( tab );
}
}
...
IN CONTROL 2009 110
198. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
// build the div
var folder = _els.div.cloneNode( true );
addClassName( folder, 'folder' );
folder.setAttribute( 'id', _id + '-' + k );
folder.innerHTML = arr[k];
_cabinet.appendChild( folder );
// build the tab
var tab = _els.li.cloneNode( true );
tab.folder = folder.getAttribute( 'id' );
tab.setAttribute( 'id', tab.folder + '-tab' );
tab.onclick = swap; // set the action
var heading = folder.getElementsByTagName( _tag )[0];
tab.innerHTML = heading.innerHTML;
addClassName( heading, 'hidden' );
_index.appendChild( tab );
}
}
...
IN CONTROL 2009 110
199. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
// build the div
var folder = _els.div.cloneNode( true );
addClassName( folder, 'folder' );
folder.setAttribute( 'id', _id + '-' + k );
folder.innerHTML = arr[k];
_cabinet.appendChild( folder );
// build the tab
var tab = _els.li.cloneNode( true );
tab.folder = folder.getAttribute( 'id' );
tab.setAttribute( 'id', tab.folder + '-tab' );
tab.onclick = swap; // set the action
var heading = folder.getElementsByTagName( _tag )[0];
tab.innerHTML = heading.innerHTML;
addClassName( heading, 'hidden' );
_index.appendChild( tab );
}
}
...
IN CONTROL 2009 110
200. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
...
// active?
if( k == 0 ){
addClassName( folder, 'visible' );
_active = folder.getAttribute( 'id' );
addClassName( tab, 'active-tab' );
}
}
// add the index
_index.className = 'tab-list';
_cabinet.appendChild( _index );
}
...
};
IN CONTROL 2009 111
201. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
...
// active?
if( k == 0 ){
addClassName( folder, 'visible' );
_active = folder.getAttribute( 'id' );
addClassName( tab, 'active-tab' );
}
}
// add the index
_index.className = 'tab-list';
_cabinet.appendChild( _index );
}
...
};
IN CONTROL 2009 111
202. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function swap( e ){
e = ( e ) ? e : event;
var tab = e.target || e.srcElement;
removeClassName( document.getElementById( _active + '-tab' ), 'active-tab' );
removeClassName( document.getElementById( _active ), 'visible' );
addClassName( tab, 'active-tab' );
addClassName( document.getElementById( tab.folder ), 'visible' );
_active = tab.folder;
}
...
};
IN CONTROL 2009 112
203. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function swap( e ){
e = ( e ) ? e : event;
var tab = e.target || e.srcElement;
removeClassName( document.getElementById( _active + '-tab' ), 'active-tab' );
removeClassName( document.getElementById( _active ), 'visible' );
addClassName( tab, 'active-tab' );
addClassName( document.getElementById( tab.folder ), 'visible' );
_active = tab.folder;
}
...
};
IN CONTROL 2009 112
204. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function swap( e ){
e = ( e ) ? e : event;
var tab = e.target || e.srcElement;
removeClassName( document.getElementById( _active + '-tab' ), 'active-tab' );
removeClassName( document.getElementById( _active ), 'visible' );
addClassName( tab, 'active-tab' );
addClassName( document.getElementById( tab.folder ), 'visible' );
_active = tab.folder;
}
...
};
IN CONTROL 2009 112
205. FUNDAMENTAL JAVASCRIPT
The code
function TabInterface( el, i ){
...
function swap( e ){
e = ( e ) ? e : event;
var tab = e.target || e.srcElement;
removeClassName( document.getElementById( _active + '-tab' ), 'active-tab' );
removeClassName( document.getElementById( _active ), 'visible' );
addClassName( tab, 'active-tab' );
addClassName( document.getElementById( tab.folder ), 'visible' );
_active = tab.folder;
}
...
};
IN CONTROL 2009 112
206. FUNDAMENTAL JAVASCRIPT
Greater flexibility
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
...
var heading = folder.getElementsByTagName( _tag )[0];
tab.innerHTML = heading.innerHTML;
if( heading.getAttribute( 'title' ) ){
addClassName( heading, 'hidden' );
tab.innerHTML = heading.getAttribute( 'title' )
_index.appendChild( tab );
} else {
... tab.innerHTML = heading.innerHTML;
} addClassName( heading, 'hidden' );
} }
... _index.appendChild( tab );
}; ...
}
}
...
};
IN CONTROL 2009 113
207. FUNDAMENTAL JAVASCRIPT
Greater flexibility
function TabInterface( el, i ){
function initialize(){
...
for( var k=0, aLen = arr.length; k<aLen; k++ ){
...
var heading = folder.getElementsByTagName( _tag )[0];
if( heading.getAttribute( 'title' ) ){
tab.innerHTML = heading.getAttribute( 'title' )
} else {
tab.innerHTML = heading.innerHTML;
addClassName( heading, 'hidden' );
}
_index.appendChild( tab );
...
}
}
...
};
IN CONTROL 2009 113
208. FUNDAMENTAL JAVASCRIPT
Running it
// Load up TabInterface
if( document.getElementById &&
document.getElementsByTagName &&
document.createElement ){
var cabinets = Array();
addDOMLoadEvent( function(){
var collection = document.getElementsByTagName( '*' );
for( var i=0, cLen = collection.length; i<cLen; i++ ){
if( collection[i] &&
/s*tabbeds*/.test( collection[i].className ) ){
cabinets.push( new TabInterface( collection[i], i ) );
}
}
} );
}
IN CONTROL 2009 114
209. FUNDAMENTAL JAVASCRIPT
Running it
// Load up TabInterface
if( document.getElementById &&
document.getElementsByTagName &&
document.createElement ){
var cabinets = Array();
addDOMLoadEvent( function(){
var collection = document.getElementsByTagName( '*' );
for( var i=0, cLen = collection.length; i<cLen; i++ ){
if( collection[i] &&
/s*tabbeds*/.test( collection[i].className ) ){
cabinets.push( new TabInterface( collection[i], i ) );
}
}
} );
}
IN CONTROL 2009 114
210. FUNDAMENTAL JAVASCRIPT
Running it
// Load up TabInterface
if( document.getElementById &&
document.getElementsByTagName &&
document.createElement ){
var cabinets = Array();
addDOMLoadEvent( function(){
var collection = document.getElementsByTagName( '*' );
for( var i=0, cLen = collection.length; i<cLen; i++ ){
if( collection[i] &&
/s*tabbeds*/.test( collection[i].className ) ){
cabinets.push( new TabInterface( collection[i], i ) );
}
}
} );
}
IN CONTROL 2009 114
211. FUNDAMENTAL JAVASCRIPT
Running it
// Load up TabInterface
if( document.getElementById &&
document.getElementsByTagName &&
document.createElement ){
var cabinets = Array();
addDOMLoadEvent( function(){
var collection = document.getElementsByTagName( '*' );
for( var i=0, cLen = collection.length; i<cLen; i++ ){
if( collection[i] &&
/s*tabbeds*/.test( collection[i].className ) ){
cabinets.push( new TabInterface( collection[i], i ) );
}
}
} );
}
IN CONTROL 2009 114
223. FUNDAMENTAL JAVASCRIPT
The code
var Easy = {
addClassName: function( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
},
removeClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
},
hasClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) return true;
}
return false;
}
};
IN CONTROL 2009 124
224. FUNDAMENTAL JAVASCRIPT
The code
var Easy = {
addClassName: function( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
},
removeClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
},
hasClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) return true;
}
return false;
}
};
IN CONTROL 2009 124
225. FUNDAMENTAL JAVASCRIPT
The code
var Easy = {
addClassName: function( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
},
removeClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
},
hasClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) return true;
}
return false;
}
};
IN CONTROL 2009 124
226. FUNDAMENTAL JAVASCRIPT
The code
var Easy = {
addClassName: function( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
},
removeClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
},
hasClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) return true;
}
return false;
}
};
IN CONTROL 2009 124
227. FUNDAMENTAL JAVASCRIPT
The code
var Easy = {
addClassName: function( e, c ){
var classes = ( !e.className ) ? [] : e.className.split( ' ' );
classes.push( c );
e.className = classes.join( ' ' );
},
removeClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) classes.splice( i, 1 );
}
e.className = classes.join( ' ' );
},
hasClassName: function( e, c ){
var classes = e.className.split( ' ' );
for( var i=classes.length-1; i>=0; i-- ){
if( classes[i] == c ) return true;
}
return false;
}
};
IN CONTROL 2009 124
228. FUNDAMENTAL JAVASCRIPT
The code
var CollapsingForm = Class.create();
CollapsingForm.prototype = {
link: document.createElement( 'a' ),
linkText: [ document.createTextNode( 'More options' ),
document.createTextNode( 'Fewer options' ) ],
hidden: [],
state: false,
id: false,
};
IN CONTROL 2009 125
229. FUNDAMENTAL JAVASCRIPT
The code
var CollapsingForm = Class.create();
CollapsingForm.prototype = {
link: document.createElement( 'a' ),
linkText: [ document.createTextNode( 'More options' ),
document.createTextNode( 'Fewer options' ) ],
hidden: [],
state: false,
id: false,
};
IN CONTROL 2009 125
230. FUNDAMENTAL JAVASCRIPT
The code
var CollapsingForm = Class.create();
CollapsingForm.prototype = {
link: document.createElement( 'a' ),
linkText: [ document.createTextNode( 'More options' ),
document.createTextNode( 'Fewer options' ) ],
hidden: [],
state: false,
id: false,
};
IN CONTROL 2009 125
231. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
// set the id
this.id = i;
// get the fieldsets
var coll = form.getElementsByTagName( 'fieldset' );
// look for hiddens
var hide = false;
for( var i=coll.length-1; i>=0; i-- ){
if( coll[i].className.indexOf( 'hide-me' ) != -1 ){
hide = true;
Easy.addClassName( coll[i], 'hidden' );
Easy.removeClassName( coll[i], 'hide-me' );
this.hidden.push( coll[i] );
}
}
// more to come
}
};
IN CONTROL 2009 126
232. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
// set the id
this.id = i;
// get the fieldsets
var coll = form.getElementsByTagName( 'fieldset' );
// look for hiddens
var hide = false;
for( var i=coll.length-1; i>=0; i-- ){
if( coll[i].className.indexOf( 'hide-me' ) != -1 ){
hide = true;
Easy.addClassName( coll[i], 'hidden' );
Easy.removeClassName( coll[i], 'hide-me' );
this.hidden.push( coll[i] );
}
}
// more to come
}
};
IN CONTROL 2009 126
233. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
// set the id
this.id = i;
// get the fieldsets
var coll = form.getElementsByTagName( 'fieldset' );
// look for hiddens
var hide = false;
for( var i=coll.length-1; i>=0; i-- ){
if( coll[i].className.indexOf( 'hide-me' ) != -1 ){
hide = true;
Easy.addClassName( coll[i], 'hidden' );
Easy.removeClassName( coll[i], 'hide-me' );
this.hidden.push( coll[i] );
}
}
// more to come
}
};
IN CONTROL 2009 126
234. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
// set the id
this.id = i;
// get the fieldsets
var coll = form.getElementsByTagName( 'fieldset' );
// look for hiddens
var hide = false;
for( var i=coll.length-1; i>=0; i-- ){
if( coll[i].className.indexOf( 'hide-me' ) != -1 ){
hide = true;
Easy.addClassName( coll[i], 'hidden' );
Easy.removeClassName( coll[i], 'hide-me' );
this.hidden.push( coll[i] );
}
}
// more to come
}
};
IN CONTROL 2009 126
235. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
...
// stop if no hiddens
if( hide === false ) return;
this.state = 'less';
// create & append the link to the first fieldset
this.link = document.createElement( 'a' );
this.link.className = 'show-hide-link';
this.link.setAttribute( 'href', '#' );
Event.observe( this.link, 'click',
this.toggle.bindAsEventListener( this ), false );
this.link.appendChild( this.linkText[0] );
coll[0].appendChild( this.link );
Easy.addClassName( form, 'collapsible' );
Easy.removeClassName( form, 'collapsing' );
}
};
IN CONTROL 2009 127
236. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
...
// stop if no hiddens
if( hide === false ) return;
this.state = 'less';
// create & append the link to the first fieldset
this.link = document.createElement( 'a' );
this.link.className = 'show-hide-link';
this.link.setAttribute( 'href', '#' );
Event.observe( this.link, 'click',
this.toggle.bindAsEventListener( this ), false );
this.link.appendChild( this.linkText[0] );
coll[0].appendChild( this.link );
Easy.addClassName( form, 'collapsible' );
Easy.removeClassName( form, 'collapsing' );
}
};
IN CONTROL 2009 127
237. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
...
// stop if no hiddens
if( hide === false ) return;
this.state = 'less';
// create & append the link to the first fieldset
this.link = document.createElement( 'a' );
this.link.className = 'show-hide-link';
this.link.setAttribute( 'href', '#' );
Event.observe( this.link, 'click',
this.toggle.bindAsEventListener( this ), false );
this.link.appendChild( this.linkText[0] );
coll[0].appendChild( this.link );
Easy.addClassName( form, 'collapsible' );
Easy.removeClassName( form, 'collapsing' );
}
};
IN CONTROL 2009 127
238. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
initialize: function( form, i ){
...
// stop if no hiddens
if( hide === false ) return;
this.state = 'less';
// create & append the link to the first fieldset
this.link = document.createElement( 'a' );
this.link.className = 'show-hide-link';
this.link.setAttribute( 'href', '#' );
Event.observe( this.link, 'click',
this.toggle.bindAsEventListener( this ), false );
this.link.appendChild( this.linkText[0] );
coll[0].appendChild( this.link );
Easy.addClassName( form, 'collapsible' );
Easy.removeClassName( form, 'collapsing' );
}
};
IN CONTROL 2009 127
239. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
initialize: function( form, i ){
...
},
toggle: function(){
if( this.state == 'less' ){
this.showMore();
} else {
this.showLess();
}
},
showMore: function(){
// code to come
},
showLess: function(){
// code to come
}
};
IN CONTROL 2009 128
240. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
initialize: function( form, i ){
...
},
toggle: function(){
if( this.state == 'less' ){
this.showMore();
} else {
this.showLess();
}
},
showMore: function(){
// code to come
},
showLess: function(){
// code to come
}
};
IN CONTROL 2009 128
241. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
showMore: function(){
for( var i=0; i<this.hidden.length; i++ ){
Easy.removeClassName( this.hidden[i], 'hidden' );
}
this.link.replaceChild( this.linkText[1], this.link.childNodes[0] );
this.state = 'more';
},
showLess: function(){
for( var i=0; i<this.hidden.length; i++ ){
Easy.addClassName( this.hidden[i], 'hidden' );
}
this.link.replaceChild( this.linkText[0], this.link.childNodes[0] );
this.state = 'less';
}
};
IN CONTROL 2009 129
242. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
showMore: function(){
for( var i=0; i<this.hidden.length; i++ ){
Easy.removeClassName( this.hidden[i], 'hidden' );
}
this.link.replaceChild( this.linkText[1], this.link.childNodes[0] );
this.state = 'more';
},
showLess: function(){
for( var i=0; i<this.hidden.length; i++ ){
Easy.addClassName( this.hidden[i], 'hidden' );
}
this.link.replaceChild( this.linkText[0], this.link.childNodes[0] );
this.state = 'less';
}
};
IN CONTROL 2009 129
243. FUNDAMENTAL JAVASCRIPT
The code
CollapsingForm.prototype = {
...
showMore: function(){
for( var i=0; i<this.hidden.length; i++ ){
Easy.removeClassName( this.hidden[i], 'hidden' );
}
this.link.replaceChild( this.linkText[1], this.link.childNodes[0] );
this.state = 'more';
},
showLess: function(){
for( var i=0; i<this.hidden.length; i++ ){
Easy.addClassName( this.hidden[i], 'hidden' );
}
this.link.replaceChild( this.linkText[0], this.link.childNodes[0] );
this.state = 'less';
}
};
IN CONTROL 2009 129
247. FUNDAMENTAL JAVASCRIPT
Popular Libraries
๏ jQuery (jquery.com)
๏ Prototype (prototypejs.org) & Scriptaculous (script.aculo.us)
๏ YUI (developer.yahoo.com/yui)
๏ Dojo (dojotoolkit.org)
๏ Spry (labs.adobe.com/technologies/spry)
๏ MooTools (mootools.net)
๏ MochiKit (mochikit.com)
IN CONTROL 2009 133
248. FUNDAMENTAL JAVASCRIPT
Popular Libraries
๏ jQuery - fast & easy to write, selector-based
๏ Prototype & Scriptaculous - powerful, Ruby-like
๏ YUI - powerful, backed by Yahoo!
๏ Dojo - powerful, backed by IBM
๏ Spry - supported in Dreamweaver, backed by Adobe
๏ MochiKit - powerful, Python-like
IN CONTROL 2009 134
249. FUNDAMENTAL JAVASCRIPT
Popular Libraries
๏ jQuery - fast & easy to write, selector-based
๏ Prototype & Scriptaculous - powerful, Ruby-like
๏ YUI - powerful, backed by Yahoo!
IN CONTROL 2009 134
250. FUNDAMENTAL JAVASCRIPT
Getters 2.0
๏ jQuery:
‣ $(selector)
‣ $(selector).attr(attribute)
๏ Prototype:
‣ $(id) or $$(selector)
‣ $$(selector).readAttribute(attribute)
๏ YUI:
‣ YAHOO.util.Dom.get(id) or YAHOO.util.Selector.query(selector)
‣ YAHOO.util.Dom.getAttribute(element, attribute)
IN CONTROL 2009 135
251. FUNDAMENTAL JAVASCRIPT
Setters 2.0
๏ jQuery:
‣ $(x).text(text) or $(x).html(html) or $(x).append([el|text])
‣ $(x).attr([attr, value|map])
๏ Prototype:
‣ $(x).insert([text|element]) // after by default
‣ $(x).writeAttribute([attr, value|map])
๏ YUI:
‣ YAHOO.util.Dom.insertAfter( [str|el], reference)
‣ YAHOO.util.Dom.addClass(el, class)
IN CONTROL 2009 136
As an example of how graceful degradation would look at a website, here’s the “hi-fi” version of my own site.
Graceful degradation would assume that my site should look roughly like this in all modern browsers and roughly like this [switch] in older browsers. It’s usable, but isn’t great. We can do better.
By contrast, PE would tell me to look at this site from the content-out and work to determine the best way to meet my users’ needs. It’s about your site and its content adapting to users instead of forcing users to get by with the scraps you’ve left them.
By contrast, PE would tell me to look at this site from the content-out and work to determine the best way to meet my users’ needs. It’s about your site and its content adapting to users instead of forcing users to get by with the scraps you’ve left them.
By contrast, PE would tell me to look at this site from the content-out and work to determine the best way to meet my users’ needs. It’s about your site and its content adapting to users instead of forcing users to get by with the scraps you’ve left them.
By contrast, PE would tell me to look at this site from the content-out and work to determine the best way to meet my users’ needs. It’s about your site and its content adapting to users instead of forcing users to get by with the scraps you’ve left them.
Developing a website is a lot like waiting tables...
* some people drink a lot* some drink very littlewe need to anticipate and meet our customers’ needs in as seemless a way possible. They should never have to ask us for more water. That’s customer service.
Taking it a bit further...
As a waiter, you’d never throw water in a customer’s face. That would be bad customer service. But websites do it all the time when they don’t build with PE in mind.
We’ll touch on an example shortly.
You need to wield your power wisely.
Let me spin a yarn...
DHTML, which arrived in the mid-90s, was awful.
How many were doing JavaScript at the time? How many liked it? How many looked @ JavaScript and said “no way”?
I don’t blame you, it was spaghetti code. Code forking. Forked ourselves. Truth be told, however, our HTML was spaghetti too.
DHTML, which arrived in the mid-90s, was awful.
How many were doing JavaScript at the time? How many liked it? How many looked @ JavaScript and said “no way”?
I don’t blame you, it was spaghetti code. Code forking. Forked ourselves. Truth be told, however, our HTML was spaghetti too.
Things are better now, but we have new challenges. We need to move from thinking about what Javascript can do that’s cool to how it should be used to improve the user experience.
[slide] And there’s a balance there that PE helps with maintaining as it does put a focus on content.
Things are better now, but we have new challenges. We need to move from thinking about what Javascript can do that’s cool to how it should be used to improve the user experience.
[slide] And there’s a balance there that PE helps with maintaining as it does put a focus on content.
Things are better now, but we have new challenges. We need to move from thinking about what Javascript can do that’s cool to how it should be used to improve the user experience.
[slide] And there’s a balance there that PE helps with maintaining as it does put a focus on content.
The reason I got in to JS: solid foundation to build neat stuff on - XHTML & HTTP.
Ajax is cool, but we should never lose sight of the fact that these are the two core technologies that drive the web. Without either, websites would cease to be.
The reason I got in to JS: solid foundation to build neat stuff on - XHTML & HTTP.
Ajax is cool, but we should never lose sight of the fact that these are the two core technologies that drive the web. Without either, websites would cease to be.
The reason I got in to JS: solid foundation to build neat stuff on - XHTML & HTTP.
Ajax is cool, but we should never lose sight of the fact that these are the two core technologies that drive the web. Without either, websites would cease to be.
And if you try to leapfrog over either, you’re doomed.
This is one statement I always want you to keep in mind when you’re working with JavaScript. And here’s an example of why:
And if you try to leapfrog over either, you’re doomed.
This is one statement I always want you to keep in mind when you’re working with JavaScript. And here’s an example of why:
What happens if JS is off?
Unfortunately you still see this all over the web... if I hear of any of you doing it, I will track you down.
For a while, we thought this was a good improvement over the previous because at least there was an action for the user if Javascript was off, but it’s not maintainable.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We then started to think about externalizing the scripting to functions like this.
We can do so much better with far less code.
We can do so much better with far less code.
We can do so much better with far less code.
We can do so much better with far less code.
We can do so much better with far less code.
We can do so much better with far less code.
We can do so much better with far less code.
We can do so much better with far less code.
Who remembers this little treat?
I’d like you to think about your web work like the McDLT, where JavaScript and CSS are separated as much as humanly possible. Why? because it makes a lot of things easier.
Who remembers this little treat?
I’d like you to think about your web work like the McDLT, where JavaScript and CSS are separated as much as humanly possible. Why? because it makes a lot of things easier.
Who remembers this little treat?
I’d like you to think about your web work like the McDLT, where JavaScript and CSS are separated as much as humanly possible. Why? because it makes a lot of things easier.
CSS was poorly understood back then, but we know better now...don’t we? Don’t be so sure.
CSS was poorly understood back then, but we know better now...don’t we? Don’t be so sure.
This was taken from a popular JavaScript library. I won’t say which, but most of them have stuff like this.
That’s an accessibility issue
But what if best practices change?
Your Javascript needs to be flexible to be maintainable. Just like the McDLT, JavaScript and CSS come together to create a tasty treat, but to be at their best, they need a little separation.
in this example, I’m using a function (addClassName) that adds CLASS names in a maintainable way
(Prototype has an element method like this)
Simple and straightforward. Scripts like sIFR that require some manual edits to the CSS take this path.
Requires diligence in implementation to keep errors out.
Numerous widget scripts and libraries take this path (Lightbox, for instance).
Still requires implementation to be error-free.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Relies only on the JS and CSS being in the same folder. It doesn’t matter where though.
Implementation example.
Implementation example.
Implementation example.
Implementation example.
Implementation example.
Implementation example.
Implementation example.
Implementation example.
Implementation example.
Implementation example.
A little messier, but still very maintainable.
A little messier, but still very maintainable.
A little messier, but still very maintainable.
A little messier, but still very maintainable.
A little messier, but still very maintainable.
A little messier, but still very maintainable.
A little messier, but still very maintainable.
A little messier, but still very maintainable.
your CSS would be added in the configuration of the script and would be easy to maintain and update along with the script as it is a single file. You are still including the two together, but it is a little more separation than writing inline styles.
your CSS would be added in the configuration of the script and would be easy to maintain and update along with the script as it is a single file. You are still including the two together, but it is a little more separation than writing inline styles.
your CSS would be added in the configuration of the script and would be easy to maintain and update along with the script as it is a single file. You are still including the two together, but it is a little more separation than writing inline styles.
your CSS would be added in the configuration of the script and would be easy to maintain and update along with the script as it is a single file. You are still including the two together, but it is a little more separation than writing inline styles.
your CSS would be added in the configuration of the script and would be easy to maintain and update along with the script as it is a single file. You are still including the two together, but it is a little more separation than writing inline styles.
your CSS would be added in the configuration of the script and would be easy to maintain and update along with the script as it is a single file. You are still including the two together, but it is a little more separation than writing inline styles.
separate your style rules from others by prefacing them in some way with the name of the script
Prototype stores its version info as a string
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Using Jesse Skinner’s addDOMLoadEvent()
Talk about client and lack of modern computers & mobile.