info343/lectures/javascript-basic-dom/lecture12-dom-timers.shtml

<!--#include virtual="commontop.html" -->
      <title>Web Programming Step by Step, Lecture 12: DOM and Timers</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><em>Web Programming Step by Step</em>, Lecture 12</h1>
            <h2>DOM and Timers</h2>
         </div>
      </div>

      <div class="presentation">
         <div class="slide">
            <h1><a href="http://www.webstepbook.com/">Web Programming Step by Step</a></h1>
            <h3>Lecture 12 <br /> DOM and Timers</h3>
            <h4>Reading: 7.2 - 7.3; 8.2; 9.1; 9.2.6</h4>

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

            <div class="w3c">
               <a href="http://validator.w3.org/check/referer"><img src="images/w3c-xhtml11.png" alt="Valid XHTML 1.1" /></a>
               <a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="images/w3c-css.png" alt="Valid CSS!" /></a>
            </div>
         </div>
         
         
         
         <div class="slide">
            <h1>
               Document Object Model
               (<a href="http://www.w3.org/TR/2004/PR-DOM-Level-3-Core-20040205/introduction.html">DOM</a>)
               <span class="readingsection">(7.1.4)</span>
            </h1>
            
            <p class="description">
               a set of JavaScript objects that represent each element on the page
            </p>
            
            <div class="rightfigure">
               <img src="images/dom.png" alt="DOM" style="width: 100%" />
            </div>

            <ul>
               <li>most JS code manipulates elements on an HTML page</li>
               <li>we can examine elements' state
                  <ul>
                     <li>e.g. see whether a box is checked</li>
                  </ul>
               <li>we can change state
                  <ul>
                     <li>e.g. insert some new text into a <code>div</code></li>
                  </ul>
               </li>
               <li>we can change styles
                  <ul>
                     <li>e.g. make a paragraph red</li>
                  </ul>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>
               DOM element objects
               <span class="readingsection">(7.2.5)</span>
            </h1>
            
            <div class="figure">
               <img src="images/figure_5_dom.png" alt="dom object" />
            </div>
            
            <ul>
               <li>
                  every element on the page has a corresponding DOM object
               </li>
               <li>
                  access/modify the attributes of the DOM object with <code><var>objectName</var>.<var>attributeName</var></code>
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>Accessing elements: <code>document.getElementById</code></h1>

            <pre class="syntaxtemplate js">
var <var>name</var> = document.getElementById(&quot;<var>id</var>&quot;);
</pre>

            <div class="example" style="float: left; width: 60%">
               <pre class="examplecode html">
&lt;img <em>id=&quot;doctor&quot;</em> src="tenth_doctor.jpg"
  alt="The Doctor" /&gt; &lt;br/&gt;
&lt;button onclick=&quot;regenerate();&quot;&gt;
  Regenerate!
&lt;/button&gt;
</pre>

               <pre class="examplecode examplecode2 js">
function regenerate() {
   var img = <em>document.getElementById(&quot;doctor&quot;)</em>;
   <em>img.src</em> = &quot;eleventh_doctor.jpg&quot;;
}
</pre>
            </div>

            <script type="text/javascript">
               function regenerate() {
                  var img = document.getElementById("doctor");
                  img.src = "images/eleventh_doctor.jpg";
               }
            </script>
            <div class="exampleoutput" style="float: right; width: 30%; margin-left: 5%">
<img id="doctor" src="images/tenth_doctor.jpg" alt="The Doctor" /> <br/>
<button onclick="regenerate();">Regenerate!</button>
            </div>
            
            <ul>
               <li>
                  <code>document.getElementById</code> returns the DOM object for an element with a given <code>id</code>
               </li>
               <li>
                  can modify properties of the element to change content on screen
               </li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>
               DOM object properties
               <span class="readingsection">(7.2.5)</span>
            </h1>

            <pre class="examplecode html">
&lt;div <em>id=&quot;main&quot;</em> class=&quot;foo bar&quot;&gt;
   &lt;p&gt;Hello, &lt;em&gt;very&lt;/em&gt; happy to see you!&lt;/p&gt;
   &lt;img <em>id=&quot;icon&quot;</em> src=&quot;images/borat.jpg&quot; alt=&quot;Borat&quot; /&gt;
&lt;/div&gt;
</pre>

            <table class="standard">
               <tr>
                  <th>
                     Property
                  </th>
                  <th>
                     Description
                  </th>
                  <th>
                     Example
                  </th>
               </tr>
               
               <tr>
                  <td>
                     <code>tagName</code>
                  </td>
                  <td>
                     element's HTML tag
                  </td>
                  <td>
                     <code>$(&quot;main&quot;).tagName</code> is <code>&quot;DIV&quot;</code>
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>className</code>
                  </td>
                  <td>
                     CSS classes of element
                  </td>
                  <td>
                     <code>$(&quot;main&quot;).className</code> is <code>&quot;foo bar&quot;</code>
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>innerHTML</code>
                  </td>
                  <td>
                     content inside element
                  </td>
                  <td>
                     <code>$(&quot;main&quot;).innerHTML</code> is <code>&quot;\n &lt;p&gt;Hello, &lt;em&gt;ve...</code>
                  </td>
               </tr>

               <tr>
                  <td>
                     <code>src</code>
                  </td>
                  <td>
                     URL target of an image
                  </td>
                  <td>
                     <code>$(&quot;icon&quot;).src</code> is <code>&quot;images/borat.jpg&quot;</code>
                  </td>
               </tr>
            </table>
         </div>
         
         
         
         <div class="slide">
            <h1>DOM properties for form controls</h1>

            <div class="example">
               <pre class="examplecode html">
&lt;input <em>id=&quot;sid&quot;</em> type=&quot;text&quot; size=&quot;7&quot; maxlength=&quot;7&quot; /&gt;
&lt;input <em>id=&quot;frosh&quot;</em> type=&quot;checkbox&quot; checked=&quot;checked&quot; /&gt; Freshman?
</pre>

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

            <table class="standard">
               <tr>
                  <th>
                     Property
                  </th>
                  <th>
                     Description
                  </th>
                  <th>
                     Example
                  </th>
               </tr>
               
               <tr>
                  <td>
                     <code>value</code>
                  </td>
                  <td>
                     the text in an input control
                  </td>
                  <td>
                     <code>$(&quot;sid&quot;).value</code> could be <code>&quot;1234567&quot;</code>
                  </td>
               </tr>
               
               <tr>
                  <td>
                     <code>checked</code>
                  </td>
                  <td>
                     whether a box is checked
                  </td>
                  <td>
                     <code>$(&quot;frosh&quot;).checked</code> is <code>true</code>
                  </td>
               </tr>
               
               <tr>
                  <td>
                     <code>disabled</code>
                  </td>
                  <td>
                     whether a control is disabled (boolean)
                  </td>
                  <td>
                     <code>$(&quot;frosh&quot;).disabled</code> is <code>false</code>
                  </td>
               </tr>
               
               <tr>
                  <td>
                     <code>readOnly</code>
                  </td>
                  <td>
                     whether a text box is read-only
                  </td>
                  <td>
                     <code>$(&quot;sid&quot;).readOnly</code> is <code>false</code>
                  </td>
               </tr>
            </table>
         </div>
         
         
         
         <div class="slide">
            <h1>
               Modifying text content: <code>value</code> vs. <code>innerHTML</code>
               <span class="readingsection">(8.2.1)</span>
            </h1>
            
            <div class="example">
<pre class="examplecode html">
&lt;p id=&quot;welcome&quot;&gt;Go away, you&#x27;re not welcome here.&lt;/p&gt;
</pre>
<pre class="examplecode examplecode2 js">
var paragraph = document.getElementById(&quot;welcome&quot;);
<span class="comment">// change text inside an opening and closing tag</span>
<em>paragraph.innerHTML =</em> &quot;Welcome to our site!&quot;;
</pre>
            </div>

            <div class="example">
<pre class="examplecode html">
&lt;input type=&quot;text&quot; id=&quot;username&quot; value="stepp" /&gt;
</pre>
<pre class="examplecode examplecode2 js">
var textbox = document.getElementById(&quot;username&quot;);
<span class="comment">// change text inside text box</span>
<em>textbox.value =</em> &quot;mdoocy&quot;;
</pre>
            </div>
            
            <p>Two ways to set the text of an element, depending on its type:</p>
            
            <ul>
               <li><code>innerHTML</code> : set text between opening and closing tags (most regular elements)</li>
<!--               <li><code>textContent</code> : text (no HTML tags) inside a node
                  <ul>
                     <li>
                        simpler than <code>innerHTML</code>, but not supported in IE6
                     </li>
                  </ul>
               </li>-->
               <li><code>value</code> : set text inside a text box (form control)
                  <ul>
                     <li>for form elements in general, sets the value that will be submitted for that element</li>
                     <li>on <code>textarea</code>s (which have opening and closing tags), only <code>value</code> works as expected in all browsers</li>
                  </ul>
               </li>
            </ul>
         </div>
         
         
         
         <div class="slide">
            <h1>More advanced example</h1>

            <div class="example">
               <pre class="examplecode html">
&lt;button onclick=&quot;swapText();&quot;&gt;Click me!&lt;/button&gt;
&lt;span <em>id=&quot;output2&quot;</em>&gt;Hello&lt;/span&gt;
&lt;input <em>id=&quot;textbox2&quot;</em> type=&quot;text&quot; value=&quot;Goodbye&quot; /&gt;
</pre>

               <pre class="examplecode examplecode2 js">
function swapText() {
   var span = document.getElementById(&quot;output2&quot;);
   var textBox = document.getElementById(&quot;textbox2&quot;);
   var temp = <em>span.innerHTML</em>;
   span.innerHTML = <em>textBox.value</em>;
   textBox.value = temp;
}
</pre>

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

            <ul>
               <li>
                  can change the text inside most elements by setting the <code>innerHTML</code> property
               </li>
               <li>
                  for form controls, <code>value</code> must be used instead
               </li>
            </ul>
         </div>



         <div class="slide">
            <h1>Abuse of <code>innerHTML</code></h1>
            
<pre class="examplecode js badcode">
<span class="comment">// bad style!</span>
var paragraph = document.getElementById(&quot;welcome&quot;);
paragraph.innerHTML = <em class="bad">&quot;&lt;p&gt;text and &lt;a href=&quot;page.html&quot;&gt;link&lt;/a&gt;&quot;</em>;
</pre>

            <ul>
               <li><code>innerHTML</code> can inject arbitrary HTML content into the page</li>
               <li>however, this is prone to bugs and errors and is considered poor style</li>
               <li>we forbid using <code>innerHTML</code> to inject HTML tags;  inject plain text only
                  <ul>
                     <li>(later, we'll see a better way to inject content with HTML tags in it)</li>
                  </ul>
               </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>
         -->
         
         
         
         <!-- *** font enlarger -->
         
         
         
         <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>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>
               Timer functions
               <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 <em>onclick=&quot;delayMsg();&quot;</em>&gt;Click me!&lt;/button&gt;
&lt;span <em>id=&quot;output&quot;</em>&gt;&lt;/span&gt;
</pre>

               <pre class="examplecode examplecode2 js">
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 html">
&lt;button <em>onclick=&quot;delayMsg2();&quot;</em>&gt;Click me!&lt;/button&gt;
&lt;span <em>id=&quot;output2&quot;</em>&gt;&lt;/span&gt;
</pre>

               <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;output2&quot;).innerHTML += &quot; Rudy!&quot;;
}
</pre>

               <div class="exampleoutput">
                  <script type="text/javascript">
                     var timer = null;
                     
                     function delayMsg2() {
                        if (timer == null) {
                           timer = setInterval(rudy, 1000);
                        } else {
                           clearInterval(timer);
                           timer = null;
                        }
                     };

                     function rudy() {
                        document.getElementById("rudy_output2").innerHTML += " Rudy!";
                     };
                  </script>
                  
                  <button onclick="delayMsg2();">Click me!</button>
                  <span id="rudy_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="commonbottom.html" -->