info343/lectures/unobtrusive-styling-timers/index.shtml

<!--#include virtual="../s5/commontop.html" -->
      <title>Lecture 8: Unobtrusive JavaScript, DOM styling &amp; Timers — INFO 343 Autumn 2011</title>
   </head>

   <body>
      <div class="layout">
         <div id="controls"><!-- DO NOT EDIT --></div>
         <div id="currentSlide"><!-- DO NOT EDIT --></div>
         <div id="header"></div>
         <div id="footer">
            <h1>INFO 343 Lecture 8</h1>
            <h2>Unobtrusive JavaScript, DOM styling &amp; Timers</h2>
         </div>
      </div>

      <div class="presentation">
         <div class="slide">
            <h1>Unobtrusive JavaScript, DOM styling &amp; Timers</h1>
            <h3>Lecture 8</h3>
            <h4>Reading: 8.1–8.2, 9.2.6</h4>

            <p class="license">
               Except where otherwise noted, the contents of this presentation are Copyright 2010 Marty Stepp, Jessica Miller, and/or Morgan Doocy.
            </p>

            <div class="w3c">
               <a href="http://validator.w3.org/check/referer"><img src="../s5/images/w3c-xhtml11.png" alt="Valid XHTML 1.1" /></a>
               <a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="../s5/images/w3c-css.png" alt="Valid CSS!" /></a>
            </div>
         </div>
         
         
         <div class="slide">
            <h1>Problems with JavaScript</h1>

            <p>
               JavaScript is a powerful language, but it has many flaws:
            </p>

            <ul>
               <li>the DOM can be clunky to use</li>
               <li>the same code doesn't always work the same way in every browser
                  <ul>
                     <li>code that works great in Firefox, Safari, ... will fail in IE and vice versa</li>
                  </ul>
               </li>
               <li>many developers work around these problems with hacks (checking if browser is IE, etc.)
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               <a href="http://prototypejs.org/">Prototype</a> framework
               <span class="readingsection">(9.1.1)</span>
            </h1>

<pre class="examplecode js" style="font-size: smaller">
&lt;script <em>src=&quot;http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js&quot;</em> 
 type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</pre>

            <ul>
               <li>the <a href="http://prototypejs.org/">Prototype</a> JavaScript library adds many useful features to JavaScript:
                  <ul>
                     <li>many useful <a class="popup" href="http://prototypejs.org/learn/extensions">extensions to the DOM</a></li>
                     <li>added methods to String, Array, Date, Number, Object</li>
                     <li>improves event-driven programming</li>
                     <li>many cross-browser compatibility fixes</li>
                     <li>makes <a class="popup" href="http://prototypejs.org/learn/introduction-to-ajax">Ajax programming</a> easier (seen later)</li>
                  </ul>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               The <a href="http://www.prototypejs.org/api/utility/dollar"><code>$</code></a> function
               <span class="readingsection">(9.1.3)</span>
            </h1>

            <pre class="syntaxtemplate js">
$(&quot;<var>id</var>&quot;)
</pre>

            <ul>
               <li>
                  returns the DOM object representing the element with the given <code>id</code>
               </li>
               <li>
                  short for <code>document.getElementById(&quot;<var>id</var>&quot;)</code>
               </li>
               <li>
                  often used to write more concise DOM code:

                  <pre class="examplecode js">
$(&quot;footer&quot;).innerHTML = $(&quot;username&quot;).value.toUpperCase();
</pre>
               </li>
            </ul>
         </div>




         <div class="slide">
            <h1>Obtrusive event handlers (bad)</h1>

            <div class="example">
               <pre class="examplecode html">
&lt;button <em class="bad">onclick=&quot;okayClick();&quot;</em>&gt;OK&lt;/button&gt;
</pre>

               <pre class="examplecode js">
<span class="comment">// called when OK button is clicked</span>
function okayClick() {
   alert(&quot;booyah&quot;);
}
</pre>

               <div class="exampleoutput insertoutput"></div>
            </div>

            <ul>
               <li>this is bad style (HTML is cluttered with JS code)</li>
               <li>goal: remove all JavaScript code from the HTML body</li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>Attaching an event handler in JavaScript code</h1>

            <pre class="syntaxtemplate js">
<span class="comment">// where <var>element</var> is a DOM element object</span>
<var>element</var>.<var>event</var> = <var>function</var>;
</pre>

            <div class="example">
               <pre class="examplecode html">
&lt;button <em>id=&quot;ok&quot;</em>&gt;OK&lt;/button&gt;
</pre>
               <pre class="examplecode js">
$(&quot;ok&quot;).<em>onclick</em> = <em>okayClick</em>;
</pre>

               <div class="exampleoutput insertoutput"></div>
            </div>
            
            <ul>
               <li>it is legal to attach event handlers to elements' DOM objects in your JavaScript code
                  <ul>
                     <li>
                        notice that you do <strong>not</strong> put parentheses after the function's name
                     </li>
                  </ul>
               </li>
               <li>this is better style than attaching them in the HTML</li>
               <li>Where should we put the above code?</li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>When does my code run?</h1>

            <div class="example">
<pre class="examplecode html">
   &lt;head&gt;
      <em>&lt;script src=&quot;myfile.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</em>
   &lt;/head&gt;

   &lt;body&gt; ... &lt;/body&gt;
</pre>

<pre class="examplecode examplecode2 examplecodelast js">
<span class="comment">// global code</span>
var x = 3;
function f(n) { return n + 1; }
function g(n) { return n - 1; }
x = f(x);
</pre>
            </div>
            
            <ul>
               <li>your file's JS code runs the moment the browser loads the <code>script</code> tag
                  <ul>
                     <li>
                        any variables are declared immediately
                     </li>
                     <li>
                        any functions are declared but not called, unless your global code explicitly calls them
                     </li>
                  </ul>
               </li>
               <li class="incremental">at this point in time, the browser has not yet read your page's <code>body</code>
                  <ul>
                     <li>
                        none of the DOM objects for tags on the page have been created yet
                     </li>
                  </ul>
               </li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>A failed attempt at being unobtrusive</h1>

            <div class="example">
<pre class="examplecode html">
   &lt;head&gt;
      <em>&lt;script src=&quot;myfile.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</em>
   &lt;/head&gt;

   &lt;body&gt;
      &lt;div&gt;&lt;button id=&quot;ok&quot;&gt;OK&lt;/button&gt;&lt;/div&gt;
</pre>

<pre class="examplecode examplecode2 examplecodelast js">
<span class="comment">// global code</span>
<em class="bad">$(&quot;ok&quot;).onclick = okayClick;</em>   <span class="comment">// error: $("ok") is null</span>
</pre>
            </div>
            
            <ul>
               <li>problem: global JS code runs the moment the script is loaded</li>
               <li>script in <code>head</code> is processed before page's <code>body</code> has loaded
                  <ul>
                     <li>no elements are available yet or can be accessed yet via the DOM</li>
                  </ul>
               </li>
               <li>we need a way to attach the handler after the page has loaded...</li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               The <code>window.onload</code> event
               <span class="readingsection">(8.1.1)</span>
            </h1>

<pre class="syntaxtemplate js">
<span class="comment">// just declaring this function now; it doesn't execute yet</span>
function <var>functionName</var>() {
   <var>element</var>.<var>event</var> = <var>functionName</var>;
   <var>element</var>.<var>event</var> = <var>functionName</var>;
   ...
}

<span class="comment">// tell the browser to run <var>functionName</var> as soon as the HTML
// has finished loading</span>
<em>window.onload = <var>functionName</var>;</em>
</pre>
            
            <ul>
               <li>we want to attach our event handlers right after the HTML is done loading</li>
                  <ul>
                     <li>there is a global event called <code>window.onload</code> that occurs at that moment</li>
                  </ul>
               <li>in <code>window.onload</code> handler we attach all the other handlers to run when events occur</li>
            </ul>
         </div>



         <div class="slide">
            <h1>An unobtrusive event handler</h1>

            <div class="example">
               <pre class="examplecode html">
<span class="comment">&lt;!-- look Ma, no JavaScript! --&gt;</span>
&lt;button id=&quot;ok&quot;&gt;OK&lt;/button&gt;
</pre>

               <pre class="examplecode examplecode2 js">
<span class="comment">// called when page loads; sets up event handlers</span>
function pageLoad() {
   $(&quot;ok&quot;).onclick = okayClick;</em>
}

function okayClick() {
   alert(&quot;booyah&quot;);
}

<em>window.onload = pageLoad;</em>  <span class="comment">// global code</span>
</pre>
               <div class="exampleoutput">
                  <button onclick="alert('booyah');">OK</button>
               </div>
            </div>
         </div>



         <div class="slide">
            <h1>Common unobtrusive JS errors</h1>
            
            <ul>
               <li>many students mistakenly write <code>()</code> when attaching the handler

<pre class="examplecode js">
<del>window.onload = pageLoad();</del>
window.onload = <em>pageLoad</em>;

<del>okButton.onclick = okayClick();</del>
okButton.onclick = <em>okayClick</em>;
</pre>

                  <ul>
                     <li>our <span class="term">JSLint</span> checker will catch this mistake</li>
                  </ul>
               </li>

               <li>event names are all lowercase, not capitalized like most variables

<pre class="examplecode js">
<del>window.onLoad = pageLoad;</del>
window.<em>onload</em> = pageLoad;
</pre>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               Anonymous functions
               <span class="readingsection">(8.1.2)</span>
            </h1>

            <pre class="syntaxtemplate js">
function(<var>parameters</var>) {
   <var>statements</var>;
}
</pre>

            <ul>
               <li>JavaScript allows you to declare <span class="term">anonymous functions</span></li>
               <li>quickly creates a function without giving it a name</li>
               <li>can be stored as a variable, attached as an event handler, etc.</li>
            </ul>
         </div>



         <div class="slide">
            <h1>Anonymous function example</h1>

            <div class="example">
               <pre class="examplecode js">
window.onload = <em>function() {</em>
   var okButton = document.getElementById(&quot;ok&quot;);
   okButton.onclick = okayClick;
<em>};</em>

function okayClick() {
   alert(&quot;booyah&quot;);
}
</pre>
               <div class="exampleoutput">
                  <button onclick="alert('booyah');">OK</button>
               </div>
            </div>
            
            <ul>
               <li>or the following is also legal (though harder to read and bad style):</li>
            </ul>

<pre class="examplecode js">
window.onload = <em>function() {</em>
   var okButton = document.getElementById(&quot;ok&quot;);
   okButton.onclick = <em>function() {</em>
      alert(&quot;booyah&quot;);
   <em>};</em>
<em>};</em>
</pre>
         </div>
         
         
         
         <div class="slide">
            <h1>Anonymous vs. named functions</h1>
            
            <p>The following are exactly equivalent:</p>
            
            <div class="example">
               <pre class="examplecode js">
var <em>foo</em> = function() {
   // ...
};
</pre>
            </div>
            <div class="example">
               <pre class="examplecode js">
function <em>foo</em>() {
   // ...
}
</pre>
            </div>
            
            <p>In either case we can use the function names like variables, executing the function only when parentheses are added:</p>
            
            <div class="example">
               <pre class="examplecode js">
var <em>bar</em> = <em>foo</em>;
// the following runs the same function twice
<em>foo</em>();
<em>bar</em>();
</pre>
            </div>
            
         </div>
         
         
         
         <div class="slide">
            <h1>
               The keyword <code>this</code>
               <span class="readingsection">(8.1.3)</span>
            </h1>
            
<pre class="syntaxtemplate js">
this.<var>fieldName</var>                  <span class="comment">// access field</span>
this.<var>fieldName</var> = <var>value</var>;          <span class="comment">// modify field</span>

this.<var>methodName</var>(<var>parameters</var>);    <span class="comment">// call method</span>
</pre>

            <ul>
               <li>
                  all JavaScript code actually runs inside of an object
               </li>
               <li>
                  by default, code runs inside the global <code>window</code> object
                  
                  <ul>
                     <li>
                        all global variables and functions you declare become part of <code>window</code>
                     </li>
                  </ul>
               </li>
               <li>
                  the <code>this</code> keyword refers to the current object
               </li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>
               Event handler binding
            </h1>
            
            <div class="example">
               <pre class="examplecode js">
function pageLoad() {
   <em>$(&quot;ok&quot;).onclick = okayClick;</em>   <span class="comment">// bound to okButton here</span>
}

function okayClick() {           <span class="comment">// okayClick knows what DOM object</span>
   <em>this</em>.innerHTML = &quot;booyah&quot;;     <span class="comment">// it was called on</span>
}

window.onload = pageLoad;
</pre>
               
               <div class="exampleoutput">
                  <button id="ok" onclick="this.innerHTML = 'booyah';">OK</button>
               </div>
            </div>

            <ul>
               <li>event handlers attached unobtrusively are <span class="term">bound</span> to the element</li>
               <li>inside the handler, that element becomes <code>this</code> (rather than the <code>window</code>)
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>Fixing redundant code with <code>this</code></h1>
            
<pre class="examplecode html">
&lt;fieldset&gt;
   &lt;label&gt;&lt;input type=&quot;radio&quot; name=&quot;ducks&quot; <em>value=&quot;Huey&quot;</em>  /&gt; Huey&lt;/label&gt;
   &lt;label&gt;&lt;input type=&quot;radio&quot; name=&quot;ducks&quot; <em>value=&quot;Dewey&quot;</em> /&gt; Dewey&lt;/label&gt;
   &lt;label&gt;&lt;input type=&quot;radio&quot; name=&quot;ducks&quot; <em>value=&quot;Louie&quot;</em> /&gt; Louie&lt;/label&gt;
&lt;/fieldset&gt;
</pre>

<pre class="examplecode js">
function processDucks() {
<del class="bad">   if ($(&quot;huey&quot;).checked) {
      alert(&quot;Huey is checked!&quot;);
   } else if ($(&quot;dewey&quot;).checked) {
      alert(&quot;Dewey is checked!&quot;);
   } else {
      alert(&quot;Louie is checked!&quot;);
   }</del>
   <span class="errorfixed">alert(<em>this.value + </em>&quot; is checked!&quot;);</span>
}
</pre>

            <ul>
               <li>if the same function is assigned to multiple elements, each gets its own bound copy</li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>
               Adjusting styles with the DOM
               <span class="readingsection">(8.2.2)</span>
            </h1>

            <div class="example">
               <pre class="examplecode html">
&lt;button id=&quot;clickme&quot;&gt;Color Me&lt;/button&gt;
</pre>

               <pre class="examplecode examplecode2 js">
window.onload = function() {
   document.getElementById(&quot;clickme&quot;).onclick = changeColor;
};
function changeColor() {
   var clickMe = document.getElementById(&quot;clickme&quot;);
   <em>clickMe.style.color = &quot;red&quot;;</em>
}
</pre>

               <div class="exampleoutput">
                  <button onclick="this.style.color = 'red';">Color Me</button>
               </div>
            </div>

            <table class="standard">
               <tr>
                  <th>Property</th>
                  <th>Description</th>
               </tr>

               <tr>
                  <td>
                     <a class="popup" href="http://www.w3schools.com/HTMLDOM/dom_obj_style.asp"><code>style</code></a>
                  </td>
                  <td>
                     lets you set any CSS style property for an element
                  </td>
               </tr>
            </table>

            <ul>
               <li>contains same properties as in CSS, but with <code>camelCasedNames</code>
                  <ul>
                     <li>examples: <code>backgroundColor</code>, <code>borderLeftWidth</code>, <code>fontFamily</code></li>
                  </ul>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>Common DOM styling errors</h1>

            <ul>
               <li>many students forget to write <code>.style</code> when setting styles

<pre class="examplecode js">
var clickMe = document.getElementById(&quot;clickme&quot;);
<del>clickMe.color = &quot;red&quot;;</del>
clickMe<em>.style</em>.color = &quot;red&quot;;
</pre>
               </li>

               <li>style properties are capitalized <code>likeThis</code>, not <code>like-this</code>

<pre class="examplecode js">
<del>clickMe.style.font-size = &quot;14pt&quot;;</del>
clickMe.style.<em>fontSize</em> = &quot;14pt&quot;;
</pre>
               </li>

               <li>style properties must be set as strings, often with units at the end

<pre class="examplecode js">
<del>clickMe.style.width = 200;</del>
clickMe.style.width = <em>&quot;200px&quot;</em>;
clickMe.style.padding = <em>&quot;0.5em&quot;</em>;
</pre>

                  <ul>
                     <li>write exactly the value you would have written in the CSS, but in quotes</li>
                  </ul>
               </li>
            </ul>
         </div>



         
         <div class="slide">
            <h1>COMMON BUG: incorrect units on styles</h1>

<pre class="examplecode js">
theDiv.style.left = x;   <span class="comment">// BAD! should be x + "px"</span>
theDiv.style.backgroundPosition = x + "px" + y + "px";    <span class="comment">// BAD! missing space</span>
</pre>

            <ul>
               <li>all CSS property values must be Strings, and many require units and/or a specific format</li>
               <li><span class="term">Manifestation of bug</span>: code fails silently; style is not set</li>
               <li><span class="term">Detection</span>: use Firebug debugger, step through code and look at <code>style</code></li>
               <li><span class="term">Detection</span>: use an <code>alert</code> immediately after style property is set

<pre class="examplecode js">
theDiv.style.left = 100;   <span class="comment">// BAD!</span>
<span class="emphasizedcode">alert(&quot;div left is &quot; + theDiv.style.left);</span>
</pre>

               </li>
            </ul>
         </div>
         

         <!-- <div class="slide">
            <h1>Common bug: Getting existing styles</h1>

            <pre class="examplecode js">
<del>this.style.fontSize = this.style.fontSize + 10 + &quot;px&quot;;</del>            <span class="comment">// bad!</span>
</pre>

            <ul>
               <li>Unless we have set the <code>fontSize</code> before, JS code can't access it</li>
               <li>So the above code has no effect</li>
            </ul>
         </div> -->
         
         

         <!-- *** font enlarger -->



         <div class="slide">
            <h1>
               Problems with reading/changing styles
            </h1>

            <div class="example">
               <pre class="examplecode html">
&lt;button id=&quot;clickme&quot;&gt;Click Me&lt;/button&gt;
</pre>

               <pre class="examplecode examplecode2 js">
document.observe('dom:loaded', function() {
   $(&quot;clickme&quot;).onclick = biggerFont;
});
function biggerFont() {
   <em class="bad">var size = parseInt($(&quot;clickme&quot;).style.fontSize);</em>
   size += 4;
   $(&quot;clickMe&quot;).style.fontSize = size + &quot;pt&quot;;
}
</pre>

               <div class="exampleoutput">
                  <button>Click Me</button>
               </div>
            </div>

            <ul>
               <li><a class="popup" href="http://www.w3schools.com/HTMLDOM/dom_obj_style.asp"><code>style</code></a> property lets you set any CSS style for an element
                  <ul>
                     <li>this is equivalent to directly editing the HTML <code>style</code> attribute on the tag</li>
                  </ul>
               </li>
               <li>
                  problem: you cannot (usually) read existing styles with it
                  <ul>
                     <li>Unless we have set its <code>.style.fontSize</code> before using JS, or included it in the HTML <code>style</code> attribute, that property doesn’t exist in the <code>style</code> attribute</li>
                     <li>So JS code attempting to read the current style has no effect</li>
                  </ul>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               Accessing styles in Prototype
               <span class="readingsection">(9.1.4)</span>
            </h1>

            <div class="example">
               <pre class="examplecode js">
function biggerFont() {
   <span class="comment">// turn text yellow and make it bigger</span>
   var size = parseInt($(&quot;clickme&quot;).<em>getStyle</em>(&quot;font-size&quot;));
   $(&quot;clickme&quot;).style.fontSize = (size + 4) + &quot;pt&quot;;
}
</pre>

               <div class="exampleoutput">
                  <button style="font-size: 20pt !important;" onclick="var s = parseInt(this.style.fontSize); this.style.setProperty('font-size', s + 4 + 'pt', 'important');">Click Me</button>
               </div>
            </div>

            <ul>
               <li><code>getStyle</code> function added to DOM object allows accessing existing styles</li>
               <li><code>addClassName</code>, <code>removeClassName</code>, <code>hasClassName</code> manipulate CSS classes</li>
            </ul>
         </div>



         <div class="slide">
            <h1>Common bug: incorrect usage of existing styles</h1>

            <pre class="examplecode js">
<del>this.style.top = this.getStyle(&quot;top&quot;) + 100 + &quot;px&quot;;</del>            <span class="comment">// bad!</span>
</pre>

            <ul>
               <li>the above example computes e.g. 
                  <code>&quot;200px&quot; + 100 + &quot;px&quot;</code> , <br />
                  which would evaluate to <code>&quot;200px100px&quot;</code>
               </li>
               <li>
                  a corrected version:
               </li>
            </ul>

            <pre class="examplecode js">
this.style.top = <em>parseInt(</em>this.getStyle(&quot;top&quot;)<em>)</em> + 100 + &quot;px&quot;;  <span class="comment">// correct</span>
</pre>
         </div>


         <div class="slide">
            <h1>
               Unobtrusive styling
               <span class="readingsection">(8.2.3)</span>
            </h1>

<pre class="examplecode js">
function okayClick() {
   <del>this.style.color = &quot;red&quot;;</del>
   this.<em>className = &quot;highlighted&quot;</em>;
}
</pre>

<pre class="examplecode css">
.<em>highlighted</em> { color: red; }
</pre>
            
            <ul>
               <li>well-written JavaScript code should contain as little CSS as possible</li>
               <li>use JS to set CSS classes/IDs on elements</li>
               <li>define the styles of those classes/IDs in your CSS file</li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               Setting CSS classes in Prototype
               <span class="readingsection">(9.1.4)</span>
            </h1>

<pre class="examplecode js">
function highlightField() {
   <span class="comment">// turn text yellow and make it bigger</span>
   if (!$(&quot;text&quot;).<em>hasClassName</em>(&quot;invalid&quot;)) {
      $(&quot;text&quot;).<em>addClassName</em>(&quot;highlight&quot;);
   }
}
</pre>

            <ul>
               <li><code>addClassName</code>, <code>removeClassName</code>, <code>hasClassName</code> manipulate CSS classes</li>
               <li>
                  similar to existing <code>className</code> DOM property, but don't have to manually split by spaces
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               Timer events
               <span class="readingsection">(9.2.6)</span>
            </h1>
            
            <div class="topfigure" style="width: 12%">
               <img src="images/timer.gif" alt="timer" style="width: 100%" />
            </div>
            
            <table class="standard">
               <tr>
                  <th>
                     method
                  </th>
                  <th>
                     description
                  </th>
               </tr>
               
               <tr>
                  <td>
                     <code><a href="http://www.w3schools.com/htmldom/met_win_settimeout.asp">setTimeout</a>(<var>function</var>,&nbsp;<var>delayMS</var>);</code>
                  </td>
                  <td>
                     arranges to call given function after given delay in ms
                  </td>
               </tr>

               <tr>
                  <td>
                     <code><a href="http://www.w3schools.com/htmldom/met_win_setinterval.asp">setInterval</a>(<var>function</var>,&nbsp;<var>delayMS</var>);</code>
                  </td>
                  <td>
                     arranges to call function repeatedly every <var>delayMS</var> ms
                  </td>
               </tr>
               
               <tr>
                  <td>
                     <code><a href="http://www.w3schools.com/htmldom/met_win_cleartimeout.asp">clearTimeout</a>(<var>timerID</var>);</code> <br />
                     <code><a href="http://www.w3schools.com/htmldom/met_win_clearinterval.asp">clearInterval</a>(<var>timerID</var>);</code>
                  </td>
                  <td>
                     stops the given timer so it will not call its function
                  </td>
               </tr>
            </table>
            
            <ul>
               <li>
                  both <code>setTimeout</code> and <code>setInterval</code> return an ID representing the timer
                  <ul>
                     <li>
                        this ID can be passed to <code>clearTimeout</code>/<code>Interval</code> later to stop the timer
                     </li>
                  </ul>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               <code>setTimeout</code></a> example</a>
            </h1>

            <div class="example">
               <pre class="examplecode html">
&lt;button id=&quot;button&quot;&gt;Click me!&lt;/button&gt;
&lt;span <em>id=&quot;output&quot;</em>&gt;&lt;/span&gt;
</pre>

               <pre class="examplecode examplecode2 js">
window.onload = function() {
   $(&quot;button&quot;).onclick = <em>delayMsg</em>;
};

function delayMsg() {
   <em>setTimeout(booyah, 5000)</em>;
   $(&quot;output&quot;).innerHTML = &quot;Wait for it...&quot;;
}

function booyah() {   <span class="comment">// called when the timer goes off</span>
   $(&quot;output&quot;).innerHTML = &quot;BOOYAH!&quot;;
}
</pre>

               <div class="exampleoutput">
                  <button onclick="document.getElementById('output').innerHTML = 'Wait for it...'; setTimeout(&quot;document.getElementById('output').innerHTML = 'BOOYAH!';&quot;, 5000)">Click me!</button>
                  <span id="output"></span>
               </div>
            </div>
         </div>



         <div class="slide">
            <h1>
               <code>setInterval</code> example
            </h1>

            <div class="example">
               <pre class="examplecode examplecode2 js">
<em>var timer = null;</em>  <span class="comment">// stores ID of interval timer</span>

function delayMsg2() {
   if (timer == null) {
      <em>timer = setInterval(rudy, 1000)</em>;
   } else {
      <em>clearInterval(timer)</em>;
      timer = null;
   }
}

function rudy() {   <span class="comment">// called each time the timer goes off</span>
   $(&quot;output&quot;).innerHTML += &quot; Rudy!&quot;;
}
</pre>

               <div class="exampleoutput">
                  <script type="text/javascript">
                     window.timer = null;

                     window.delayMsg2 = function() {
                        if (timer == null) {
                           timer = setInterval(rudy, 1000);
                        } else {
                           clearInterval(timer);
                           timer = null;
                        }
                     };

                     window.rudy = function() {
                        document.getElementById("output2").innerHTML += " Rudy!";
                     };
                  </script>
                  
                  <button onclick="delayMsg2();">Click me!</button>
                  <span id="output2"></span>
               </div>
            </div>
         </div>



         <div class="slide">
            <h1>Passing parameters to timers</a></h1>

            <div class="example">
               <pre class="examplecode js">
function delayedMultiply() {
   <span class="comment">// 6 and 7 are passed to multiply when timer goes off</span>
   setTimeout(multiply, 2000<em>, 6, 7</em>);
}
function multiply(<em>a, b</em>) {
   alert(a * b);
}
</pre>

               <div class="exampleoutput insertoutput">
                  <button onclick="delayedMultiply();">Click me</button>
               </div>
            </div>

            <ul>
               <li>any parameters after the delay are eventually passed to the timer function
                  <ul>
                     <li>doesn't work in IE6; must create an intermediate function to pass the parameters</li>
                  </ul>
               </li>
               <li>
                  why not just write this?
                  <pre class="examplecode js">
setTimeout(<em>multiply(6 * 7)</em>, 2000);
</pre>
               </li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>Common timer errors</h1>
            
            <ul>
               <li>
                  many students mistakenly write <code>()</code> when passing the function

                  <pre class="examplecode js">
<del>setTimeout(booyah(), 2000);</del>
setTimeout(<em>booyah</em>, 2000);

<del>setTimeout(multiply(num1 * num2), 2000);</del>
setTimeout(<em>multiply</em>, 2000<em>, num1, num2</em>);
</pre>

                  <ul>
                     <li>what does it actually do if you have the <code>()</code> ?</li>
                     <li class="incremental">it calls the function immediately, rather than waiting the 2000ms!</li>
                  </ul>
               </li>
            </ul>
         </div>




<!--#include virtual="../s5/commonbottom.html" -->