<!--#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("<var>id</var>");
</pre>
<div class="example" style="float: left; width: 60%">
<pre class="examplecode html">
<img <em>id="doctor"</em> src="tenth_doctor.jpg"
alt="The Doctor" /> <br/>
<button onclick="regenerate();">
Regenerate!
</button>
</pre>
<pre class="examplecode examplecode2 js">
function regenerate() {
var img = <em>document.getElementById("doctor")</em>;
<em>img.src</em> = "eleventh_doctor.jpg";
}
</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">
<div <em>id="main"</em> class="foo bar">
<p>Hello, <em>very</em> happy to see you!</p>
<img <em>id="icon"</em> src="images/borat.jpg" alt="Borat" />
</div>
</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>$("main").tagName</code> is <code>"DIV"</code>
</td>
</tr>
<tr>
<td>
<code>className</code>
</td>
<td>
CSS classes of element
</td>
<td>
<code>$("main").className</code> is <code>"foo bar"</code>
</td>
</tr>
<tr>
<td>
<code>innerHTML</code>
</td>
<td>
content inside element
</td>
<td>
<code>$("main").innerHTML</code> is <code>"\n <p>Hello, <em>ve...</code>
</td>
</tr>
<tr>
<td>
<code>src</code>
</td>
<td>
URL target of an image
</td>
<td>
<code>$("icon").src</code> is <code>"images/borat.jpg"</code>
</td>
</tr>
</table>
</div>
<div class="slide">
<h1>DOM properties for form controls</h1>
<div class="example">
<pre class="examplecode html">
<input <em>id="sid"</em> type="text" size="7" maxlength="7" />
<input <em>id="frosh"</em> type="checkbox" checked="checked" /> 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>$("sid").value</code> could be <code>"1234567"</code>
</td>
</tr>
<tr>
<td>
<code>checked</code>
</td>
<td>
whether a box is checked
</td>
<td>
<code>$("frosh").checked</code> is <code>true</code>
</td>
</tr>
<tr>
<td>
<code>disabled</code>
</td>
<td>
whether a control is disabled (boolean)
</td>
<td>
<code>$("frosh").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>$("sid").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">
<p id="welcome">Go away, you're not welcome here.</p>
</pre>
<pre class="examplecode examplecode2 js">
var paragraph = document.getElementById("welcome");
<span class="comment">// change text inside an opening and closing tag</span>
<em>paragraph.innerHTML =</em> "Welcome to our site!";
</pre>
</div>
<div class="example">
<pre class="examplecode html">
<input type="text" id="username" value="stepp" />
</pre>
<pre class="examplecode examplecode2 js">
var textbox = document.getElementById("username");
<span class="comment">// change text inside text box</span>
<em>textbox.value =</em> "mdoocy";
</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">
<button onclick="swapText();">Click me!</button>
<span <em>id="output2"</em>>Hello</span>
<input <em>id="textbox2"</em> type="text" value="Goodbye" />
</pre>
<pre class="examplecode examplecode2 js">
function swapText() {
var span = document.getElementById("output2");
var textBox = document.getElementById("textbox2");
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("welcome");
paragraph.innerHTML = <em class="bad">"<p>text and <a href="page.html">link</a>"</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">
<button id="clickme">Color Me</button>
</pre>
<pre class="examplecode examplecode2 js">
window.onload = function() {
document.getElementById("clickme").onclick = changeColor;
};
function changeColor() {
var clickMe = document.getElementById("clickme");
<em>clickMe.style.color = "red";</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("clickme");
<del>clickMe.color = "red";</del>
clickMe<em>.style</em>.color = "red";
</pre>
</li>
<li>style properties are capitalized <code>likeThis</code>, not <code>like-this</code>
<pre class="examplecode js">
<del>clickMe.style.font-size = "14pt";</del>
clickMe.style.<em>fontSize</em> = "14pt";
</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>"200px"</em>;
clickMe.style.padding = <em>"0.5em"</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("div left is " + 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 = "red";</del>
this.<em>className = "highlighted"</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">
<script <em>src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"</em>
type="text/javascript"></script>
</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">
$("<var>id</var>")
</pre>
<ul>
<li>
returns the DOM object representing the element with the given <code>id</code>
</li>
<li>
short for <code>document.getElementById("<var>id</var>")</code>
</li>
<li>
often used to write more concise DOM code:
<pre class="examplecode js">
$("footer").innerHTML = $("username").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>, <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>, <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">
<button <em>onclick="delayMsg();"</em>>Click me!</button>
<span <em>id="output"</em>></span>
</pre>
<pre class="examplecode examplecode2 js">
function delayMsg() {
<em>setTimeout(booyah, 5000)</em>;
$("output").innerHTML = "Wait for it...";
}
function booyah() { <span class="comment">// called when the timer goes off</span>
$("output").innerHTML = "BOOYAH!";
}
</pre>
<div class="exampleoutput">
<button onclick="document.getElementById('output').innerHTML = 'Wait for it...'; setTimeout("document.getElementById('output').innerHTML = 'BOOYAH!';", 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">
<button <em>onclick="delayMsg2();"</em>>Click me!</button>
<span <em>id="output2"</em>></span>
</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>
$("output2").innerHTML += " Rudy!";
}
</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" -->