Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Fundamental JavaScript [In Control 2009]

5.149 visualizaciones

Publicado el

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.

Publicado en: Tecnología
  • Sé el primero en comentar

Fundamental JavaScript [In Control 2009]

  1. 1. FUNDAMENTAL JAVASCRIPT Aaron Gustafson
  2. 2. DOM SCRIPTING (a.k.a. Document Manipulation via JavaScript)
  3. 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. 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. 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
  6. 6. FUNDAMENTAL JAVASCRIPT The DOM html IN CONTROL 2009 6
  7. 7. FUNDAMENTAL JAVASCRIPT The DOM html head body title meta meta h1 p ul a li li li IN CONTROL 2009 6
  8. 8. FUNDAMENTAL JAVASCRIPT The DOM p this is a paragraph a . of text with a href=quot;http://easy-reader.netquot; link IN CONTROL 2009 6
  9. 9. FUNDAMENTAL JAVASCRIPT CSS getter { setter } IN CONTROL 2009 7
  10. 10. FUNDAMENTAL JAVASCRIPT CSS p { color: red; } IN CONTROL 2009 7
  11. 11. FUNDAMENTAL JAVASCRIPT CSS #footer { font-size: small; } IN CONTROL 2009 7
  12. 12. FUNDAMENTAL JAVASCRIPT DOM Scripting IN CONTROL 2009 8
  13. 13. FUNDAMENTAL JAVASCRIPT DOM Scripting var myNode = document.getter(); IN CONTROL 2009 8
  14. 14. FUNDAMENTAL JAVASCRIPT DOM Scripting myNode.setter(); IN CONTROL 2009 8
  15. 15. FUNDAMENTAL JAVASCRIPT Getters ๏ document.getElementById( ID ); ๏ document.getElementsByTagName( tagName ); ๏ element.getAttribute( attributeName ); IN CONTROL 2009 9
  16. 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. 17. FUNDAMENTAL JAVASCRIPT Language comparison ๏ English Get the element with the ID “content”. ๏ CSS #content { } ๏ DOM document.getElementById( 'content' ) IN CONTROL 2009 11
  18. 18. FUNDAMENTAL JAVASCRIPT Language comparison ๏ English Get all the paragraphs in a document. ๏ CSS p { } ๏ DOM document.getElementsByTagName( 'p' ); IN CONTROL 2009 12
  19. 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. 20. FUNDAMENTAL JAVASCRIPT Content generation ๏ Bad: ‣ document.write(); ‣ innerHTML IN CONTROL 2009 14
  21. 21. FUNDAMENTAL JAVASCRIPT Content generation ๏ Good: ‣ document.createElement( tagName ); ‣ document.createTextNode( text ); ‣ element.setAttribute( name, value ); IN CONTROL 2009 15
  22. 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. 23. FUNDAMENTAL JAVASCRIPT Adding to the DOM ๏ element.appendChild( newNode ); ๏ element.insertBefore( newNode, targetNode ); IN CONTROL 2009 17
  24. 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
  25. 25. TIME FOR AN EXAMPLE
  26. 26. FUNDAMENTAL JAVASCRIPT The idea Make use of the cite attribute in blockquotes. IN CONTROL 2009 20
  27. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  44. 44. PROGRESSIVE ENHANCEMENT
  45. 45. WHAT IS PROGRESSIVE ENHANCEMENT?
  46. 46. PROGRESSIVE ENHANCEMENT VS. GRACEFUL DEGRADATION
  47. 47. GRACEFUL DEGRADATION
  48. 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
  49. 49. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 35
  50. 50. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 35
  51. 51. PROGRESSIVE ENHANCEMENT FOCUSES ON CONTENT
  52. 52. PROGRESSIVE ENHANCEMENT FOCUSES ON CONTENT
  53. 53. CONTENT IS WHY WE BUILD WEBSITES AND SHOULD BE OUR CENTRAL FOCUS
  54. 54. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 38
  55. 55. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 39
  56. 56. HOW DOES IT WORK?
  57. 57. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 41
  58. 58. FUNDAMENTAL JAVASCRIPT Flavorful nugget of content (semantic goodness) IN CONTROL 2009 42
  59. 59. FUNDAMENTAL JAVASCRIPT Rich, indulgent design IN CONTROL 2009 43
  60. 60. FUNDAMENTAL JAVASCRIPT Sweet interactivity (keeps it from melting in your hands) IN CONTROL 2009 44
  61. 61. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 45
  62. 62. TECHNOLOGIES APPLIED AS LAYERS
  63. 63. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 47
  64. 64. WEB STANDARDS: FUELING INNOVATION stuffandnonsense.co.uk/archives/web_standards_trifle.html WEB BUILDER 2.0 48
  65. 65. WHY A PEANUT M&M?
  66. 66. FUNDAMENTAL JAVASCRIPT The peanut is good for ๏ diabetics IN CONTROL 2009 50
  67. 67. FUNDAMENTAL JAVASCRIPT The peanut is good for ๏ diabetics ๏ search engine spiders IN CONTROL 2009 50
  68. 68. FUNDAMENTAL JAVASCRIPT The peanut is good for ๏ diabetics ๏ search engine spiders ๏ mobile devices IN CONTROL 2009 50
  69. 69. IT’S A BASIC LEVEL OF SUPPORT
  70. 70. FUNDAMENTAL JAVASCRIPT The chocolate is good for IN CONTROL 2009 52
  71. 71. FUNDAMENTAL JAVASCRIPT The chocolate is good for ๏ diabetics IN CONTROL 2009 52
  72. 72. FUNDAMENTAL JAVASCRIPT Rich, chocolaty goodness ๏ some browsers only handle a certain level of CSS ๏ some companies turn off JavaScript IN CONTROL 2009 52
  73. 73. IT CAN BE BEAUTIFUL (and progressive)
  74. 74. FUNDAMENTAL JAVASCRIPT The candy coating IN CONTROL 2009 54
  75. 75. FUNDAMENTAL JAVASCRIPT The candy coating ๏ JavaScript can turn a website into an experience IN CONTROL 2009 54
  76. 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
  77. 77. PROGRESSIVE ENHANCEMENT WITH JAVASCRIPT
  78. 78. RESTRAINT & PLANNING
  79. 79. FUNDAMENTAL JAVASCRIPT A long time ago, in a cubicle far, far away... Dear George Lucas, please don’t sue me. Kthxbye. IN CONTROL 2009 57
  80. 80. FUNDAMENTAL JAVASCRIPT A long time ago, in a cubicle far, far away... Dear George Lucas, please don’t sue me. Kthxbye. IN CONTROL 2009 57
  81. 81. WHAT CAN JAVASCRIPT DO?
  82. 82. HOW SHOULD JAVASCRIPT BE USED?
  83. 83. PROGRESSIVE ENHANCEMENT REMINDS US TO FOCUS ON THE CONTENT
  84. 84. FUNDAMENTAL JAVASCRIPT Back to basics IN CONTROL 2009 60
  85. 85. FUNDAMENTAL JAVASCRIPT Back to basics XHTML + HTTP IN CONTROL 2009 60
  86. 86. FUNDAMENTAL JAVASCRIPT Back to basics solid foundation IN CONTROL 2009 60
  87. 87. FUNDAMENTAL JAVASCRIPT ALL CODE NEEDED TO UNDERSTAND AND USE A SITE SHOULD EXIST BEFORE ANY SCRIPTS RUN IN CONTROL 2009 61
  88. 88. FUNDAMENTAL JAVASCRIPT PERIOD. IN CONTROL 2009 61
  89. 89. FUNDAMENTAL JAVASCRIPT Consider lala.com IN CONTROL 2009 62
  90. 90. FUNDAMENTAL JAVASCRIPT Without JavaScript IN CONTROL 2009 63
  91. 91. FUNDAMENTAL JAVASCRIPT Without JavaScript IN CONTROL 2009 63
  92. 92. FUNDAMENTAL JAVASCRIPT Without JavaScript Doh! IN CONTROL 2009 63
  93. 93. FUNDAMENTAL JAVASCRIPT And looking at the IN CONTROL 2009 64
  94. 94. FUNDAMENTAL JAVASCRIPT And looking at the Ug h ! IN CONTROL 2009 64
  95. 95. WHAT ABOUT SEARCH?
  96. 96. WHAT ABOUT ALTERNATIVE DEVICES?
  97. 97. ENTER UNOBTRUSIVE JAVASCRIPT
  98. 98. ENTER UNOBTRUSIVE JAVASCRIPT ( ) the cornerstone of Progressive Enhancement with JavaScript
  99. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  115. 115. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 71
  116. 116. JavaScript CSS
  117. 117. 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
  118. 118. 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
  119. 119. FUNDAMENTAL JAVASCRIPT Isn’t this the same? for( i=0; i<objects.length; i++){ objects[i].style.display = 'none'; } IN CONTROL 2009 74
  120. 120. FUNDAMENTAL JAVASCRIPT Small improvement for( i=0; i<objects.length; i++){ objects[i].style.position = 'absolute'; objects[i].style.left = '-999em'; } IN CONTROL 2009 75
  121. 121. FUNDAMENTAL JAVASCRIPT Separation CSS: .hidden { position: absolute; left: -999em; } JavaScript: for( i=0; i<objects.length; i++){ objects[i].addClassName( 'hidden' ); } IN CONTROL 2009 76
  122. 122. 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
  123. 123. 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
  124. 124. 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
  125. 125. 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
  126. 126. 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
  127. 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. 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. 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. 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. 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. 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. 133. 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
  134. 134. 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
  135. 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. 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. 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. 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. 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. 140. 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
  141. 141. 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
  142. 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. 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. 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. 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. 146. 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
  147. 147. 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
  148. 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. 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. 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. 151. BUT KEEP IN MIND
  152. 152. YOU NEED TO AVOID APPLYING SCRIPT-RELATED STYLES
  153. 153. UNTIL YOU KNOW YOUR SCRIPT CAN RUN AND IT HAS INITIALIZED PROPERLY
  154. 154. FUNDAMENTAL JAVASCRIPT How do we do that? ๏ make your style rules specific: .TabInterface-folder { ... } or #TabInterface .tab { ... } #TabInterface .tab.active { ... } IN CONTROL 2009 85
  155. 155. 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
  156. 156. 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
  157. 157. WEB STANDARDS: FUELING INNOVATION WEB BUILDER 2.0 87
  158. 158. FUNDAMENTAL JAVASCRIPT Look for methods function someFunction(){ if( !document.getElementsByTagName ) return; // code that uses document.getElementsByTagName() ... } IN CONTROL 2009 88
  159. 159. 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
  160. 160. 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
  161. 161. 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
  162. 162. FUNDAMENTAL JAVASCRIPT Look for objects function someFunction(){ if( typeof( Prototype ) == 'undefined' ) return; // code that uses Prototype ... } IN CONTROL 2009 92
  163. 163. 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
  164. 164. FUNDAMENTAL JAVASCRIPT Look before you leap window.onload = function(){ if( document.getElementsByTagName && document.getElementById ){ someFunction(); } }; IN CONTROL 2009 94
  165. 165. 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
  166. 166. HOW DOES IT ALL COME TOGETHER?
  167. 167. FUNDAMENTAL JAVASCRIPT Example 1: Tab Interface IN CONTROL 2009 97
  168. 168. 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
  169. 169. 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
  170. 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. 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. 172. FUNDAMENTAL JAVASCRIPT No style IN CONTROL 2009 99
  173. 173. FUNDAMENTAL JAVASCRIPT A little typography IN CONTROL 2009 100
  174. 174. FUNDAMENTAL JAVASCRIPT Typography & color IN CONTROL 2009 101
  175. 175. FUNDAMENTAL JAVASCRIPT No style IN CONTROL 2009 102
  176. 176. FUNDAMENTAL JAVASCRIPT No style .tabbed IN CONTROL 2009 102
  177. 177. 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
  178. 178. 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
  179. 179. FUNDAMENTAL JAVASCRIPT Understanding the flow IN CONTROL 2009 104
  180. 180. 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
  181. 181. 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
  182. 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. 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. 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. 185. 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
  186. 186. 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
  187. 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. 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. 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. 190. 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
  191. 191. 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
  192. 192. 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
  193. 193. 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
  194. 194. 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
  195. 195. 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
  196. 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. 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. 198. 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
  199. 199. 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
  200. 200. 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
  201. 201. 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
  202. 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. 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. 204. 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
  205. 205. 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
  206. 206. 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
  207. 207. 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
  208. 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. 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. 210. FUNDAMENTAL JAVASCRIPT The full experience IN CONTROL 2009 115
  211. 211. QUESTIONS?
  212. 212. FUNDAMENTAL JAVASCRIPT Example 2: Collapsing Form IN CONTROL 2009 117
  213. 213. FUNDAMENTAL JAVASCRIPT Collapsing Form as HTML IN CONTROL 2009 118
  214. 214. FUNDAMENTAL JAVASCRIPT Collapsing Form with CSS IN CONTROL 2009 119
  215. 215. FUNDAMENTAL JAVASCRIPT Collapsing Form with CSS IN CONTROL 2009 120
  216. 216. FUNDAMENTAL JAVASCRIPT Collapsing Form with CSS IN CONTROL 2009 121
  217. 217. FUNDAMENTAL JAVASCRIPT HTML hooks IN CONTROL 2009 122
  218. 218. FUNDAMENTAL JAVASCRIPT HTML hooks form.collapsing IN CONTROL 2009 122
  219. 219. FUNDAMENTAL JAVASCRIPT HTML hooks fieldset.optional IN CONTROL 2009 122
  220. 220. FUNDAMENTAL JAVASCRIPT Understanding the flow IN CONTROL 2009 123
  221. 221. 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
  222. 222. 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
  223. 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. 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. 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. 226. 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
  227. 227. 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
  228. 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. 229. 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
  230. 230. 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
  231. 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. 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. 233. 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
  234. 234. 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
  235. 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. 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. 237. 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
  238. 238. 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
  239. 239. 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
  240. 240. 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
  241. 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. 242. FUNDAMENTAL JAVASCRIPT Collapsing Form with JS IN CONTROL 2009 130
  243. 243. QUESTIONS?
  244. 244. WORKING WITH LIBRARIES
  245. 245. 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
  246. 246. 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
  247. 247. 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
  248. 248. 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
  249. 249. 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
  250. 250. LET’S REVISIT OUR FIRST EXAMPLE

×