The words you are searching are inside this book. To get more targeted content, please make full-text search by clicking here.
Discover the best professional documents and content resources in AnyFlip Document Base.
Search
Published by Mỹ Lê, 2019-10-29 22:07:01

Head First Javascript

head_first_javascript

wrangling the page

Standards compliant adventuring

Boy, that sounds fun! The mark of any good adventure is standards
compliance... or not. But it can be a good thing in the context of modern
web apps. And more importantly, take a look at the dramatic changes the
DOM approach to altering the scene description text have brought to
Stick Figure Adventure...

atsWsceaexbnitteeflaoodroemeks!iscnrutitphtee.i.o.snatmhee

Hmm. OK, so maybe the page doesn’t look any different, but behind The DOM is a web
the scenes it adheres to the latest web standards thanks to its usage standard way of
of the DOM. Not everything in JavaScript code can be appreciated manipulating HTML that
visually, and in this case our satisfaction with the DOM-powered allows more control than
version of Stick Figure Adventure will have to come from within. using the innerHTML
property.

you are here 4   365

Download at WoweBook.Com

improving your options

In search of better options

So now the dynamic scene description text has now been overhauled twice,
but those cryptic option buttons still remain in Stick Figure Adventure.
Surely something could be done to make the story navigation a little more
engaging and intuitive than choosing between the numbers 1 and 2!

I know they get the job done
but the option buttons really are
underwhelming. They should be
much more descriptive.

Taarbheoenu’nttumtchueetritcdineogcpitsitiioon-n fbtauhcteitnyognstasyhjeunsuotstehri.ng

A decent improvement to the option buttons would be to change them
so that they actually reflect the available decisions. They could include
text on the buttons that spell out exactly what the two options are at
each point like this:

Mplauychingbetthteerr!olNeoowf the options are
decisions.

Come to think of it, there really isn’t any reason we have to use form
buttons for this—any HTML element that can contain text could
feasibly work. CSS styles could be used to dress them up and make
them look more like input controls.

How would you implement data-driven options in Stick Figure Adventure
so that they display option text specific to each different scene?

366   Chapter 8

Download at WoweBook.Com

wrangling the page

Designing better, cleaner options decision1
decision2
Since the new and improved decision-making options in Stick Figure
Adventure are HTML elements that contain text, the DOM can be
used to dynamically alter the decision text in each scene. This means
each scene will set its decision text along with its description. And it
also means the changeScene() function needs two new variables to
store this decision text, decision1 and decision2.

Here’s how we could go about setting Scene 1 decision text as it
transitions to Scene 3 in the changeScene() function:

curScene = 3;

message = "You are standing on the bridge overlooking a peaceful stream.";

decision1 = "Walk across Bridge"; Tvtahhreeiasdbceleecnsiesaiodrnee1cuiassnieoddn decision2
decision2 = "Gaze into Stream"; to store
text for
a given scene.

Dynamic options in Stick Figure Adventure require a new approach to
how the options are represented in HTML code. Write code for the new
text elements that replace the existing <input> buttons.

Hint: The CSS style class for the new elements is named "decision",
and the content of the first element is initially set to "Start Game".

<input type="button" id="decision1" value="1" onclick="changeScene(1)" /> Rewrite the code for
<input type="button" id="decision2" value="2" onclick="changeScene(2)" /> dynamic options!

you are here 4   367

Download at WoweBook.Com

sharpen solution

Dynamic options in Stick Figure Adventure require a new approach to
how the options are represented in HTML code. Write code for the new
text elements that replace the existing <input> buttons.

Hint: The CSS style class for the new elements is named "decision",
and the content of the first element is initially set to "Start Game".

<input type="button" id="decision1" value="1" onclick="changeScene(1)" /> Rdtspwyeawnonarbmietuilectemttooephnntestioscb.noesdc..oe.tmfheoer
<input type="button" id="decision2" value="2" onclick="changeScene(2)" />

<span id=“decision1” class=“decision” onclick=“changeScene(1)”>Start Game</span>
<span id=“decision2” class=“decision” onclick=“changeScene(2)”></span>

Replacing node text sounds
like a task that would be
handy to have in a function.

Rethinking node text replacement

All that’s missing now in Stick Figure Adventure for the new dynamic
decision text is the code that actually sets the text for the new span
elements. This code is ultimately doing the exact same thing as the DOM
code we wrote earlier in the chapter that dynamically changes the scene
description text. In fact, this presents a problem because we now need
to carry out the exact same task on three different elements: the scene
description and the two scene decisions...

368   Chapter 8

Download at WoweBook.Com

wrangling the page

Replacing node text with a function

An all-purpose node text replacement function is a handy thing, and not

just in Stick Figure Adventure. This type of function operates much like

the scene description text replacement code we worked through earlier,

except this time the code goes to work on function arguments.

The ID of ttohebenordeeplawcheods.e
content is

function replaceNodeText(id, newText) {

... The new text content
} to place in the node.

The custom replaceNodeText() function accepts two arguments: the Rdaeenspcelawrcipemtteioshnseatgseec.xentewith
ID of the node whose content is to be replaced and the new text to place in ttChehexatntgwfeoortdheeeaccidshieoconifss.ion
the node. Use this function to change the text content of any element on a
page that can hold text. In Stick Figure Adventure, the function allows you
to now dynamically change the scene description text and the text for the
two decisions at one time..but of course you need to write it first.

Instead of duplicating replaceNodeText("scenetext", message);
tthimeessa, mtehecofduenctthiorneeis replaceNodeText("decision1", decision1);
called three times. replaceNodeText("decision2", decision2);

Write the code for the replaceNodeText() function, the all‑purpose
function for replacing the text within a node that is referenced by ID.
Don’t forget that the function accepts two arguments, id and newText.

you are here 4   369

Download at WoweBook.Com

sharpen solution

Get the element Write the code for the replaceNodeText() function, the all‑purpose
using its unique ID. function for replacing the text within a node that is referenced by ID.
Don’t forget that the function accepts two arguments, id and newText.

Remove all function replaceNodeText(id, newText) {
tchheildnroedne.from var node = document.getElementById(id);
while (node.firstChild)

Create a new node.removeChild(node.firstChild);
child text
element using the node.appendChild(document.createTextNode(newText));

text passed into }
the function.
The createTextNode() function is only
available in the document object, and
has no direct tie to a particular node.

Dynamic options are a good thing

The new dynamic text decisions in Stick Figure Adventure are much more
intuitive than their cryptic button counterparts.

Dynamic,
descriptive,
delightful!

370   Chapter 8 Taursheeerasntekwneoawdchyenpxaoamicnitctlydinewcthishaiteonststholeerityr.tohpetions

Download at WoweBook.Com

wrangling the page

Q: Why are span elements used for Q: When I create a new node with Q: Does the content of a text node

the Stick Figure Adventure decisions, as createTextNode(), where does created with createTextNode()
the node go? have to be just text?
opposed to div elements?
A: Nowhere. When a new text node A: Yes. The DOM doesn’t work like
A: Because the decision elements need
is first created, it’s in limbo, at least with innerHTML, where you can assign
to appear side by side, which means they respect to the DOM tree for a given page. text that has tags mixed in with it. When
can’t be block elements that start on a new It’s not until you append the node as a child the DOM talks about a “text node,” it really
of another node that it actually gets added means pure text with no other tags or
line. A div is a block element, whereas a to the tree, which then adds it to the page. formatting tacked on.
span is inline. Inline is what we want for
the decisions, so span is the ticket.

Interactive options are even better Thtihhgeehldmigeohcutissseiowpnhoteinnetxettrheeolveuemsreernittd.rags

So the dynamic text decisions in Stick Figure Adventure are an
improvement over their cryptic predecessors, but they could still be
better. For example, they could highlight when the mouse pointer
hovers over them to make it clear that they are clickable.

I thought highlighting and fancy
visual effects are associated
with CSS, not the DOM.

Highlighting is associated with CSS but the

DOM is still directly involved.

Highlighting web page content is in fact a CSS issue because
it involves tweaking the background color of an element. But
the DOM also factors into the highlighting equation because it
provides programmatic access to the CSS styles of elements...

you are here 4   371

Download at WoweBook.Com

classy DOM styles

A matter of style: CSS and DOM

CSS styles are tied to HTML elements, and the DOM provides access to
styles through elements (nodes). By using the DOM to tweak CSS styles,
it’s possible to dynamically manipulate the content presentation. One way
that CSS styles are exposed through the DOM is in an element’s style
class, which is where a group (class) of styles is applied to an element.

<span id="decision1" class="decision" onclick="changeScene(1)">Start Game</span>

<span id="decision2" class="decision" onclick="changeScene(2)"></span>

<style type="text/css"> Twthhheeaitrdgevciivsiesuisaolntahspetpyedlaeelc.cislaiosnssis
span.decision {
font-weight:bold;
border:thin solid #000000;
padding:5px;
background-color:#DDDDDD;

}
</style>

The DOM provides access to an element’s style class through the Try not to
className property of the node object. get CSS
style
alert(document.getElementById("decision1").className); classes
confused
Tperlheoemviecdnlaetss’ssNascatcmyelesespctrloaopsase.nrty
with JavaScript
The className property of a node classes.
provides access to the style class.
CSS style classes and
JavaScript classes are very
different animals. A CSS
style class is a collection of
styles that can be applied
to an element on the page,
while a JavaScript class
is a template for creating
JavaScript objects. We
uncover the details of
JavaScript classes and
objects in Chapter 10.

372   Chapter 8

Download at WoweBook.Com

wrangling the page

Swapping style classes The decisioninverse
style class reverses
To change the appearance of an element using a completely different style the color scheme of
class, just change its style class name to a different CSS style class. the decision text.

document.getElementById("decision1").className = "decisioninverse";

Same decision element, <style type="text/css">
different style classes! span.decisioninverse {
font-weight:bold;
Adenceiswionsteylleemcelnatss uissinagppclliaesdsNtaomteh.e font-color:#FFFFFF;
border:thin solid #DDDDDD;
Changing the style class of an element using the className padding:5px;
property immediately changes the appearance of the element to the background-color:#000000;
new style class. This technique can be used to make dramatic visual }
changes to elements on a page with relatively little coding effort.
</style>

Using the two mouse events onmouseover and onmouseout, add
code to the <span> decision elements in Stick Figure Adventure so
that they change style classes for a mouse hover highlight effect.
Hint: The “hover” style class is named decisionhover.

<span id="decision1" class="decision" onclick="changeScene(1)"

>Start Game</span>
<span id="decision2" class="decision" onclick="changeScene(2)"

></span>

you are here 4   373

Download at WoweBook.Com

sharpen solution

Trehsepodnesceistioonhtohveeronsmtoyulesecolvaesrs is set in Using the two mouse events onmouseover and onmouseout, add
event. code to the <span> decision elements in Stick Figure Adventure so that
they change style classes for a mouse hover highlight effect.

Hint: The “hover” style class is named decisionhover.

<span id="decision1" class="decision" onclick="changeScene(1)"

onmouseover=”this.className = ‘decisionhover’”

This event onmouseout=”this.className = ‘decision’” >Start Game</span>
is triggered
when the mouse <span id="decision2" class="decision" onclick="changeScene(2)"
pointer moves
over the span onmouseover=”this.className = ‘decisionhover’”
element.
onmouseout=”this.className = ‘decision’” ></span>

tTstohyetlehueinshoringemhstloiogurhseetodeudtinderevecesinpstioo.nnse Tpohiinsteevrenmtovisestorfigfgeorfedthwehesnpatnheelemmoeunste.

Classy options Q: Can’t I just use CSS to create buttons that highlight

Applying style classes to the Stick Figure Adventure when the mouse moves over them?
code yields two different appearances for the
decision elements: normal and highlighted. A: Yes. And in many cases that is a better way to create “hover”

buttons because CSS is more widely supported than JavaScript in
browsers, such as on some mobile devices. However, Stick Figure
Adventure is a JavaScript application, and does all kinds of things
that are impossible to do in CSS alone. So in this case it’s not a
liability in any way to use JavaScript for the scene decision buttons.

<style type="text/css"> Ttbhhaecektogwnrlooyusndtdiyflfceeorlcoelarns.cseesbeistwtheeen <style type="text/css">
span.decision { span.decisionhover {
font-weight:bold; font-weight:bold;
border:thin solid #000000; border:thin solid #000000;
padding:5px; padding:5px;
background-color:#DDDDDD; background-color:#EEEEEE;
}
}
</style> </style>

Normal Highlighted

374   Chapter 8

Download at WoweBook.Com

Test drive the stylized adventure options wrangling the page

The user interface for Stick Figure Adventure is now improved thanks to Wow, the new
the DOM’s ability to change an element’s style class on demand. Ellie is mouse hover
feeling pretty good about her script. highlighting
effect rocks!

pThoihginehtlidegrehcthisowiovhenernseleotmvheeernmttsohuensmoew.

Q: I don’t remember the Q: Why wasn’t it necessary to use Q: Style classes are cool but I’d really

onmouseover and onmouseout getElementById() in the code like to just change one style property. Is
events. Are those standard events? that sets the style class of the decision that possible?
elements?
A: Yes. In fact, there are lots of standard A: Wow, what intuition! There’s a nagging
A: Every element in JavaScript is an
JavaScript events that we haven’t explored. problem with Stick Figure Adventure that
But the thing about events is how you object, and in the HTML code for an element Ellie has been eager to resolve. And it just
can react to them even when you don’t we have access to that object through the so happens to involve using JavaScript and
necessarily know everything about them. this keyword. So in the Stick Figure the DOM to manipulate style properties
In the case of the two mouse events, their Adventure code, the this keyword individually...
names are really all you needed to know to references the node object for the span
understand that one of them is fired when element. And that’s the same object with the
the mouse pointer hovers over an element, className property that accesses its
and the other one fires when the mouse style class. So changing the style class only
pointer moves out of an element. involves setting this.className.

you are here 4   375

Download at WoweBook.Com

where the buttons have no name

Options gone wrong: the empty button

It’s been there all along, and up until this point Ellie coped with it. But It’s been bugging me that some
it’s time to go ahead and address the weirdness associated with the empty of the scenes have empty options.
decisions in Stick Figure Adventure. In some scenes there is only one An empty option doesn’t make much
viable decision yet both decision elements are still displayed, like the sense and can only cause confusion.
screenshot here. It’s a little unsettling for the user to see an interactive
decision element with no information in it.

The empty decision
element is both
strange and confusing.

376   Chapter 8 Which other scenes have the empty option
problem? What options exist to fix this?

Download at WoweBook.Com

wrangling the page

A la carte style tweaking The style property
of a node provides
Sometimes changing the entire style class of an element is just too much. access to individual
For times when a little more granularity is required, there is the style style properties.
object. The style object is accessible as a property of a node object, and
provides access to individual styles as properties. The visibility style
property can be used to show and hide elements. In the HTML for Stick
Figure Adventure, the second decision element can be initially hidden
using the following code:

<span id="decision2" class="decision" onclick="changeScene(2)"
onmouseover="this.className = 'decisionhover'"
onmouseout="this.className = 'decision'"
style="visibility:hidden"></span>

From then on, showing and hiding the element is just a matter of setting
the visibility style property to visible or hidden.

document.getElementById("decision2").style.visibility = "visible"; Poof!
document.getElementById("decision2").style.visibility = "hidden";

Second option. Some scenes in Stick Figure Adventure must alter the visibility of the second
option element when changing to a new scene. Circle these scenes, and then
annotate the decision where each scene should show or hide the option.

Scene 0 Scene 1 Scene 2 Scene 4 Scene 8

Title intro Fork in the Little house Witch in To be
road in the woods window continued...

Scene 3 Scene 5 Scene 9

Bridge Eaten by To be
overlooking witch continued...

stream THE END

Scene 6

Eaten by
troll

THE END

Scene 7

Troll on
bridge

you are here 4   377

Download at WoweBook.Com

sharpen solution

Second option. Some scenes in Stick Figure Adventure must alter the visibility of
the second option element when changing to a new scene. Circle
these scenes, and then annotate the decision where each scene
should show or hide the option.

Tbtseohucehahisdesacdcseoensnntedainwrdtieaticnnhiygsoiosancnleynneeoelwenmtegheadnamtteec.lsieshiaoodunsl,d Scene 8

Show. Scene 2 Hide. Scene 4 To be
continued...
Little house Witch in
in the woods window Hide.

Scene 0 Scene 1 Scene 5 Hide.

Title intro Fork in the Eaten by Scene 9
road witch
To be
Scene 3 Hide. THE END continued...

Bridge Scene 6
overlooking
Eaten by
stream troll

Townhhleeynsneaeceondnesdwtdogeabcmeiseisobhneogweilnnesm.oenncte, THE END

Scene 7

Troll on
bridge

sbdWcueehtcneiesntiohlteneahdecelhiengamganemguneepthetsanohsdotstu,hlodetchgboeaemmseheeicdionednnetddnhi,neg.

pehErlieadomcepheetrnshttceyeunssoeeifncmgotnuthsdtheedsstehvcyoisilwisebioioolnirbtjyect. ...
case 7:
if (decision == 1) {
cmdueerscSsicasegineoen=1="=6So"rSrtya,rtyoOuvebre"c;ame the troll's tasty lunch.";
decision2 = "";

/d/ocHuimdeentt.hgeetsEelceomnedntdBeycIids(i"odnecision2").style.visibility = "hidden";
}
else {

curScene = 9;
decision1 = "?";
decision2 = "?";
}
break;
...

378   Chapter 8

Download at WoweBook.Com

wrangling the page

 The className node property makes big style  Elements on a page can be dynamically shown or
changes by changing the entire style class of a node. hidden using the visibility style property of the
element object.
 The style node property makes small style changes
by providing access to individual style properties of a dTbaycihscpesoleamdtypit:slpiibnsllhagoycaitksts(tiymsolheilodawpirsr)po.slhpaeoyrw:nt/oyhniecdae(nheidfef)ecotr
node.

 A CSS style class has nothing to do with a JavaScript
class—they are completely different things.

No more bogus options

Manipulating individual styles using the DOM allows the
second decision element to be selectively shown and hidden.
The end result is a user interface that makes a lot more sense
now that the empty decision elements are gone.

Ah, much better...
those empty decisions
were really annoying!

The second decision element is you are here 4   379
now hidden when it isn’t needed,
such as on the title scene.

Download at WoweBook.Com

big ol’ decision tree

More options, more complexity

Ellie envisions the Stick Figure Adventure storyline growing by leaps and
bounds to reveal all kinds of interesting new scenes and decisions. There
are ways the DOM can factor into helping manage the complexity of a
much deeper Stick Figure Adventure narrative.

Scene 0 Scene 1 Scene 2 Scene 4 Scene 8 Scene 10

Title intro Fork in the Little house Witch in ... ...
road in the woods window
Scene 9 Scene 11
Scene 3 Scene 5
... ...
Bridge Eaten by THE END
overlooking witch
Scene 12
stream THE END
...
Scene 6
Scene 13
Eaten by
troll ...

THE END

Scene 7

Troll on
bridge

Deeper adventure = Bigger decision tree!

* The latest version of the Stick Figure Adventure is online and
waiting for your coding assistance. Download this at http://www.
headfirstlabs.com/books/hfjs/ if you haven’t already.

380   Chapter 8

Download at WoweBook.Com

Scene 14 Scene 18 Scene 24 wrangling the page

... ... ... Scene 28

Scene 15 Scene 19 Scene 25 ...

... ... ... Scene 29
THE END
Scene 16 Scene 26 ...
Scene 20
... ... Scene 30
...
Scene 17 Scene 27 ...
Scene 21 THE END
... ...
THE END ... THE END Scene 31

Scene 22 ...

... Wow! That’s a lot of decisions... but it seems
THE END like it would be a nightmare to test.

Scene 23 Big stories can certainly turn
into big problems without a
... way to test the decision tree.
As the story continues to unfold with
more scenes and decisions, it becomes
increasingly difficult to test the logic of
the story and make sure every decision
path leads to the right place. Stick Figure
Adventure is in desperate need of a way
to analyze paths through the story.

What do you think might be the best way to create testing
paths through such a monstrous decision tree?

you are here 4   381

Download at WoweBook.Com

following the trail

Tracking the decision tree Scene 10

Similar to the history feature in a web browser, which keeps ...
track of the sequence of pages you’ve visited, a decision
history feature in Stick Figure Adventure can be used to test 2 Scene 11
and debug the storyline. The idea is to reveal the series of ...
decisions that leads to a particular outcome. By doing this
Ellie can make sure the decision path works as expected. THE END

Scene 4 1 Scene 8 Scene 12

Scene 2 1 Witch in ... ...
window
Scene 9 Scene 13
Little house Scene 5
in the woods ... ...
Eaten by
Scene 0 1 1 witch

Title intro Scene 1 THE END

Fork in the Scene 6
road
Eaten by
Scene 3 troll

Bridge THE END
overlooking
Scene 7
stream
Troll on
bridge

The decision history is built as a list of the options and scenes that occur
in any given path through the story. The history then serves as a story
debugger that lets Ellie trace back through options and scenes.

Start Scene 0 - Title intro.

Decision 1 1 Scene 1 - Fork in the road.
is chosen... 1 Scene 2 - Little house in the woods.

1 Scene 4 - Witch in window. ... which leads
to scene 4.

1 Scene 8 - ... Eidwtsaeoitaccdhahisrditosrecnhidveeenhteidtsotehtocterirrhsayeievo,.enarslmoenadgde What kind of changes
are required to the
2 Scene 11 - ... Stick Figure Adventure
End Web page to support a
decision history feature?

382   Chapter 8

Download at WoweBook.Com

wrangling the page

Turn your decision history into HTML

From an HTML perspective, the code for the decision history isn’t too tcEhoaencthdaeipncsiesilaoenmdeehncistitsioorny.in
terribly complex: a div element and a paragraph of text for each decision
is all that is needed.

<div id="history">

<p>Decision 1 -> Scene 1 : Fork in the road.</p>

<p>Decision 1 -> Scene 2 : Little house in the woods.</p>

<p>Decision 1 -> Scene 4 : Witch in window.</p>

... A decision history
feature in Stick
</div> Figure Adventure can
be a very useful story
All that remains is writing some JavaScript to use the DOM to generate debugging tool.
the decision history as a collection of nodes.

That’s crazy. You
can’t just create
new paragraphs at
will... can you?

The DOM can create any HTML element at will,

including paragraphs of text.

Actually, you can. And it involves another method of the document
object, createElement(), which can be used to create any HTML
element. The idea is that you create a new container element using
createElement(), and then you add text content to it by creating a
child text node with createTextNode(). The end result is an entirely
new branch of nodes grafted onto the node tree of a page.

document.createElement("p"); div

document.createTextNode("... "); p ELEMENT

TEXT
"Decision 1 -> Scene 1 : Fork in the road."

you are here 4   383

Download at WoweBook.Com

monkeying around with the HTML eWleemsetnatrtfloofaftinwgitihn a new p
space.
Manufacturing HTML code

Creating a new element with the createElement() method only
requires the name of the tag. So creating a paragraph (p) element simply
means having to call the method with an argument of "p", making sure
to hang on to the resulting element that is created.

var decisionElem = document.createElement("p"); p

At this point there’s a new paragraph element with no content, and it’s
not yet part of any page either. So to add the text content to the element,
create a text node and then add it as a child of the new p node.

decisionElem.appendChild("Decision 1 -> Scene 1 : Fork in the road.")); p

The p element tisseoxsmtteillntofedlxoeta. tcionngtienntspatchea,nks
but it now has
to a new child

"Decision 1 -> Scene 1 : Fork in the road."

The last step is to add the new paragraph element to the page as a child of div
the history div element. p

document.getElementById("history").appendChild(decisionElem);

pTeaalehrcmehaegiplnrdtaep,olehfwmhieaninnctthoeximtsihesaterdignwdegseebddtihpvaeasge.

... "Decision 1 -> Scene 1 : Fork in the road."

<div id="history">
<p>Decision 1 -> Scene 1 : Fork in the road.</p>

</div>

...

By repeating these steps whenever each scene is traversed in Stick Figure
Adventure, a decision history can be created dynamically.

384   Chapter 8

Download at WoweBook.Com

wrangling the page

 Any HTML element can be created using the  By carefully adding and removing nodes in the DOM

document object’s createElement() method. tree, a web page can be disassembled and reassembled

 To add text content to an element, a child text node must at will.

be created and appended to the element.

Add code to the changeScene() function to support the decision history
feature in Stick Figure Adventure. Hint: You need to add a new paragraph
element with a child text node to the decision history element when the
current scene isn’t Scene 0, and clear the decision history if the Scene is 0.

function changeScene(decision) {
...
// Update the decision history

}

you are here 4   385

Download at WoweBook.Com

sharpen solution

Add code to the changeScene() function to support the decision history
feature in Stick Figure Adventure. Hint: You need to add a new paragraph
element with a child text node to the decision history element when the
current scene isn’t Scene 0, and clear the decision history if the Scene is 0.

Anpopadpreaengdtroatpthhheeenlenemewwentte.xt TanmlahrumeestaecddhbyaednhengaceasiSmsiaceoednlno,ecss(oao)ml tfevhuatnirhsciiantvbgiaolreneialsbel.e
dGirvaubsitnhgeithsistIDor.y
function changeScene(decision) {
...
// Update the decision history

var history = document.getElementById(“history”);

if (curScene != 0) {

// Add the latest decision to the history

var decisionElem = document.createElement(“p”);

decisionElem.appendChild(document.createTextNode(“decision “ + decision +

“ -> Scene “ + curScene + “ : “ + message));

history.appendChild(decisionElem);

Append the }
paragraph
element to the else {

div to add it // Clear the decision history
to the page.

while (history.firstChild)

history.removeChild(history.firstChild);

}

} hnCiosrdteoeartwyeitianhfnoterwhmeatdteeixoctnis.ion

Crelemaorvitnhgealhlisotforiytsdcivhibldyren.

386   Chapter 8

Download at WoweBook.Com

wrangling the page

Tracing the adventure story

The decision history feature in Stick Figure Adventure now makes it
possible to carefully track the story logic as it unfolds.

Tsohethsetroeryishnaosnh’tistsotrayr.ted

The decision history is The history
awesome! I can finally cut loose grows as the
creatively and still keep the story unfolds.
decision tree under control.

wTinhhetenhsetaondreeycnidpsiaiontnghhicsisotrmeoparlcyehteeds.

you are here 4   387

Download at WoweBook.Com

the neverending story

A long strange trip...

It’s time to flex your creative muscle by expanding the Stick Figure
Adventure story into something worthy of some serious decision history
debugging. Your stick figure friend is waiting for adventure...

Dream up your very own continuation of the Stick Figure Adventure story, and add code to
incorporate it into the Stick Figure Adventure application so that you can share it online as an
interactive adventure.
There is no solution to this exercise... just have fun dreaming up adventures!

388   Chapter 8

Download at WoweBook.Com

wrangling the page

JavaScrUinptittlcerdoPsuszzle

Before you dig too deeply into stick figure story writing, takHHe eeaaddeerr Info 1
a moment to experience a little crossword adventure! Info 2
etc...

1 2
3 4

5
6

78
9

10
11
12 13

Across Down

1. A node appearing below another node in the DOM tree is 1. Call this method to create an HTML element.
called a ...... 2. The topmost node in a DOM tree.
4. The property of a node object used to get its value. 3. A non-standard way to change the content of an HTML
5. Used to set the style class of an element. element.
7. Call this method to get all of the elements of a certain type, 6. A clumsy way to tell an online story.
such as div. 8. A leaf in a DOM tree of Web page content.
10. This type of node holds text content. 9. Use this property to access individual style properties of an
11. A DOM node type that equates to an HTML tag. element.
12. Use this method to add a node to another node as a child. 13. Set this attribute on an HTML tag to make it accessible from
JavaScript.

you are here 4   389

Download at WoweBook.Com

JavaScriptcross solution

JavaScriptcross Solution
Untitled Puzzle

Header Info 1
Header Info 2

etc...

1C H I L D 2D
3I R 4N O D E V A L U E

NE C

NA U

E T 5C L A S S N A M E

RE E 6A

HE NL

7G E T E L E M E N T S B Y T A G 8N A M E

ME O R 9S

LM D 10T E X T

E 11E L E M E N T Y

1A2 P P E N D C H 13I L D L

TD E

Across Down

1. A node appearing below another node in the DOM tree is 1. Call this method to create an HTML element.
called a ...... [CHILD] [CREATEELEMENT]
4. The property of a node object used to get its value. 2. The topmost node in a DOM tree. [DOCUMENT]
[NODEVALUE] 3. A non-standard way to change the content of an HTML
5. Used to set the style class of an element. [CLASSNAME] element. [INNERHTML]
7. Call this method to get all of the elements of a certain type, 6. A clumsy way to tell an online story. [ALERT]
such as div. [GETELEMENTSBYTAGNAME] 8. A leaf in a DOM tree of Web page content. [NODE]
10. This type of node holds text content. [TEXT] 9. Use this property to access individual style properties of an
11. A DOM node type that equates to an HTML tag. [ELEMENT] element. [STYLE]
12. Use this method to add a node to another node as a child. 13. Set this attribute on an HTML tag to make it accessible from
3[A9P0P E NDCChHaILpDte] r 8 JavaScript. [ID]

Download at WoweBook.Com

wrangling the page

Page Bender

Fold the page vertically What is the DOM, really?
to line up the two brains
and solve the riddle. It’s a meeting of the minds!

DOM Document

<html>
<head></head>

html<body> head

<div>
The DOM <span>is <strong>often</strong> confused
with</span> the browser, <span><em>which is</em>

bodyin control.</span>

</p>

</body>

</html> div ""

""

"The DOM" span "the browser, " span

"is" strong "confused with" em "in control."

"often" "which is"

A JavaScript programmer must be careful not to
get carried away with the DOM. It
is certainly handy for accessing HTML
tags. But try not to become a total

manipulator, or you may wear out your nodes.

you are here 4   391

Download at WoweBook.Com

Download at WoweBook.Com

9 bringing data to life

Objects as Frankendata

I once disassembled an entire
man with these...you can ask him...
I put him back together later.

JavaScript objects aren’t nearly as gruesome as the good
doctor might have you think. But they are interesting in that they combine

pieces and parts of the JavaScript language together so that they’re more powerful
together. Objects combine data with actions to create a new data type that is much
more "alive" than data you’ve seen thus far. You end up with arrays that can sort
themselves, strings that can search themselves, and scripts that can grow fur and
howl at the moon! OK, maybe not that last one but you get the idea...

this is a new chapter   393

Download at WoweBook.Com

party time

A JavaScript-powered party

There’s a party, and you’re responsible for the invitations. So the first
question is what information goes into the perfect party invitation?

Who? What? When? Where?

The invitee A puzzle party The date/time The location

Display! Invitation actions. Invitation data.

Display the data Deliver!

Deliver the data

A party invitation for JavaScript would model the data as variables Deliver!
and the actions as functions. Problem is, in the real world the
ability to separate data and actions doesn’t really exist.

What?

You’re invited to... Flip over! Who?
When?
A Puzzle Party! Puzzler Ruby
5280 Unravel Avenue
Date: October 24th Conundrum, AZ 85399
USA
Location: 2112 Confounding Street
Baffleburg, CA 95099

USA

Where? Display!

In the real world, the invitation card combines data and actions
into a single entity, an object.

394   Chapter 9

Download at WoweBook.Com

bringing data to life

Data + actions = object Object

You don’t always have to work with data and actions as separate things in
JavaScript. In fact, JavaScript objects combine the two into an entirely
unique data structure that both stores data and acts on that data. This
functionality allows JavaScript to apply real-world thinking to scripts. So
you can think in terms of “things” as opposed to separate data and actions.

When you look at the party invitation in terms of a JavaScript object, you
get this:

Data Actions

var who; function display(what, when, where) { function display() {
... ...

var what; } }

var when; + function deliver(who) { = var who; function deliver() {

... var what; ...

var where; } }
var when;
Odfuaunttcastidimoeunsostfabsaenarpogabusjsmeeecdtnt,inst. o
var where;

Inside the invitation object, data and functions now co-exist and have Objects link
closer ties than they had outside of the object. More specifically, functions variables
placed within an object can access variables in the object without having and functions
to pass the variables into the functions as arguments. together inside
a storage
who deliver() container.
what
Invitation

when display()

where

The data within the invitation object is accessible to the functions but
hidden from the outside world. So the object serves as a container that
stores data and links it to code that can take action on it.

you are here 4   395

Download at WoweBook.Com

membership has its privileges

An object owns its data

When variables and functions are placed within an object, they are
referred to as object members. More specifically, variables are called
object properties and functions are called object methods. They still
store data and take actions on data, they just do so within the context of a
specific object.

Variables Functions oFbujneccttiomnestbheocdosm. e

var who; function display(what, when, where) { Object
var what; ...
var when;
var where; }

function deliver(who) {
...

}

Variables become Properties Methods
object properties.
var who; function display() {
var what; ...
var when;
var where; }

function deliver() {
...

}

Properties Properties and methods are “owned” by an object, which means they
and methods are stored within the object much like data is stored in an array. Unlike
are the object arrays, however, you typically access object properties and methods using
equivalents of a special operator called the dot operator.
variables and
functions. Object + . + Property/Method

The name of Just a dot (period). The name of the
the object. property or method.

396   Chapter 9

Download at WoweBook.Com

Object member references with a dot bringing data to life

The dot operator establishes a reference between a property or method The dot operator
and the object to which it belongs. It’s kind of like how people’s first references a
names tell you who they are, but their last names tell you what family property or method
they belong to. Same thing for objects—a property name tells you what from an object.
the property is, while the object name tells you what object the property
belongs to. And the dot operator connects the two together.

Now it’s possible to actually put together the data for a JavaScript
invitation object using properties and the dot operator:

A dot! Property name.

Object name.

invitation.who = "Puzzler Ruby";
invitation.what = "A puzzle party!";
invitation.when = "October 24th";
invitation.where = "2112 Confounding Street";

Ttoheacdcoetssoepaecrhatporropiserutseyd.

Keep in mind that since the data and the actions are all part of the same
object, you don’t have to pass along anything to a method in order for it
to be able to use the data. This makes taking an action on the invitation
object quite simple:

invitation.deliver();

Object name. Method name.

The party invitation is missing an RSVP property that allows invitees to respond with whether
they will be coming to the party or not. Write code to add an rsvp property to the Puzzler Ruby
invitation (she plans to attend), and then call the sendRSVP() method to send the response.

you are here 4   397

Download at WoweBook.Com

ask me anything

The party invitation is missing an RSVP property that allows invitees to respond with whether
they will be coming to the party or not. Write code to add an rsvp property to the Puzzler Ruby
invitation (she plans to attend), and then call the sendRSVP() method to send the response.

invitation.rsvp = "attending";

invitation.sendRSVP(); Twathhtieserencdotuinrldgu,eafmlasoelsaebnesmeatahbneos optelehraesnoyn’rperisonpoetr.ty
Totfhheetphdreootipneovriptteyartaaitonondromrbeejfetechrtoe.dnces

Q: What exactly is an object? Does it truly needs access to the data. This helps an object, which is why you can get away
prevent the data from getting accidentally
have a data type? changed by other code. Q:with alert() by itself.
OK, this is really confusing. So
A: Yes, objects have a data type. An Unfortunately, JavaScript doesn’t currently you’re telling me that functions are really
allow you to truly prevent an object property methods?
object is a named collection of properties from being accessed by outside code. And
and methods. Or put more exactly, objects there are situations where you specifically A: Yes, although it can get confusing
are a data type. Other data types you’ve want an object property to be accessed
learned about include number, text, and directly. However, the idea is that you place thinking of functions in this manner. You
boolean. These are known as primitive data in an object to logically associate it with already know that a function is a chunk of
data types because they represent a the object. A piece of data tied to an object code that can be called by other code by
single piece of information. Objects are has much more context and meaning than name. A method is just a function that has
considered complex data types because a piece of data floating freely in a script (a been placed within an object. The confusion
they encompass multiple pieces of data. You arises when you realize that every function
can add "object" as a fourth data type to Q:global variable). actually belongs to an object.
the list of primitive types you already know I’ve seen object notation with the
(number, string, and boolean). So, any object dot operator used several times already. So alert() is both a function and a
you create or any built-in JavaScript object Was I really using objects all this time? method, which explains why it can be called
as a function or as a method—most methods
Q:you use has a data type of object. A: Yes. You’ll find that it’s actually quite have to be called as a method using object
Couldn’t I just use global variables notation. In reality, every JavaScript function
and functions instead of object properties difficult to use JavaScript without using belongs to an object, thereby making it a
and methods? Functions can access objects, and that’s because JavaScript method. And in many cases this object is
global variables just fine, right? itself is really one big collection of objects. the browser’s window object. Since this
For example, the alert() function object is assumed to be the default object if
A: Yes they can. Problem is, there is is technically a method of the window no object is specified for a method call, such
object, which means it can be called with as alert(), it’s OK to think of these
nothing stopping any other code from window.alert(). The window methods as functions. Their ownership by
accessing the global variables as well. This object represents the browser window, and the window object is incidental since they
is problematic because you always want to doesn’t have to be explicitly referenced as have no logical connection to the object.
try and limit data exposure only to code that

398   Chapter 9

Download at WoweBook.Com

bringing data to life

 Objects are a special kind of data structure that  When placed into an object, variables become known as
combine data with code that acts on the data. properties, while functions become known as methods.

 In practical terms, an object is really just variables and  Properties and methods are referenced by supplying the
functions combined into a single structure. name of the object followed by a dot followed by the
name of the property or method.

A blog for cube puzzlers

On the other end of the party invitation is Ruby, a cube puzzle enthusiast
who can’t wait to get together with her other puzzler friends. But Ruby
has more on her mind than just going to parties—she wants to create a
blog where she can share her love of cube puzzles with the world. She’s
ready to start sharing her cubist wisdom on YouCube!

I’ve heard that objects will make my
code easier to maintain when I need to
make changes. That will give me more
time for my cube puzzles!

Ruby has heard that JavaScript supports custom objects as a means of
creating more robust, and ultimately more manageable code. She has
also heard that lots of blogs eventually get stale because bloggers get
tired of maintaining them. So Ruby wants to start her blog out on the
right foot by building YouCube as an object-oriented script using
custom objects that will carry her far into the puzzling future.

Object-oriented = More cube
YouCube time!

you are here 4   399

Download at WoweBook.Com

be the cube TYohueChuabned. written

Deconstructing YouCube

Ruby currently has a handwritten diary, and she’s read enough blogs to know
hers will need to consist of dates and text, but she can’t figure out how to store
them using JavaScript. She just knows she’s sick of writing her cube diary
(soon to be blog) entries by hand!

08/14/2008 cube I ordered. It’s a real Each entry
Gpeoatrtl. he new consists of a date
combined with a
Date of 08/19/2008 aconuerwseo, nneo.w string of text.
entry. IS’omlvbeodrtehdeannedwshcoupbpeinbgutfoorf
the Ruby’s favorite
cube puzzle.
08/16/2008
tMhaennaegwedcutobeg. et a headache toiling over

Body text of Gotta nap.
the entry.

08/21/2008 cbuebae bfoerassta.le online. Yikes!
TFhoautndonae7cxo7uxl7d

Ruby desperately needs a straightforward way to store and access multiple A custom object allows
pairs of information (date + text). This sure sounds an awful lot like what the two pieces of blog
JavaScript objects have to offer...combining multiple pieces of information data to be combined
into a single entity. into a single entity.

Blog date + Blog body = Blog object

400   Chapter 9

Download at WoweBook.Com

bringing data to life

Custom objects extend JavaScript It’s true, strings
are really objects!
The JavaScript language includes lots of handy standard objects, several
of which we explore later in this chapter. As useful as these objects are, String
there are times when they simply aren’t enough. The YouCube blog is a
good example of this limitation since it involves a data storage problem
that can’t be solved with built-in JavaScript data types...a custom object is
in order.

Date

Standard JavaScript "Got the new
objects. cube I ordered.

Blog date. It’s a real
Blog pearl."

"08/14/2008" October 24th, 2008
"Got the new 7:00pm
cube I ordered.
It’s a real pearl." Array Arrays are
objects too.

date body
0 08/14/2008
1 08/19/2008 oGrodtertehde..n.ew cube I

YjAuosutcCufsutoboremtblohobegj!ect 2 08/16/2008 bSuotlvoefd..t.he new cube
3 08/21/2008
hMeaandaagcehde.t.o. get a

Found a 7x7x7 cube for
sale...

Wotebenitjmtehrpcoitteuisstn, giinttthaoem2ishgt-eholtDpreboaebfrlroagy.

Blog body. Custom objects allow you to add features to JavaScript that suit your own
The Blog object serves specific needs. In Ruby’s case, a custom object could model a blog entry,
as a compound data using properties to represent the blog date and body text. Additionally,
type - combining two methods can be used to add behavior to blog entries, making it more
pieces of data into one. intuitive to create and manage them.

In order to bring such a custom object to life, however, we must first find
out how custom objects are created...

you are here 4   401

Download at WoweBook.Com

caution: construction zone

Construct your custom objects A constructor is
responsible for
Since objects have data associated with them that must be initialized when creating an object.
an object is created, a special method called a constructor is required
to get an object up and running. Every custom object requires its own
constructor, which is named the same as the object. The constructor is
called to initialize an object upon creation. When creating a custom object,
it’s your job to write a suitable constructor that brings the object to life.

var who; function display() { Tachnrdeeapmtreeodtp.heordtsiesare
var what; ...

}

var when; Invitation(who, what, when, where);
function deliver() {

var where; ...

} The name of the
constructor matches
Tarheeinpirtoiapelirzteide.s Tobhjeecntewislyrcearedayted the object name.
to use.
Invitation

who = "Somebody"; Properties Methods
what = "Something";
when = "Sometime"; var who = "Somebody"; function display() {
where = "Somewhere"; var what = "Something"; ...
var when = "Sometime";
var where = "Somewhere"; }

function deliver() {
...

}

To create an object with a constructor, you use the new operator, which

kickstarts the object creation process by calling the object’s constructor.

The constructor part of creating an object looks like a call to a method

because that’s really what it is. However, it’s important to always use

the new operator to initiate the creation of an object, as opposed to just

calling an object’s constructor directly. Ttohecrneeawteopaernaetworobisjeucste.d

var invitation = new Invitation("Somebody", "Something", "Sometime", "Somewhere");

Tsthoerendewinoabjveacrtiaibsle. The constructor is The properties are set by passing
called just like a method. arguments to the constructor.

402   Chapter 9

Download at WoweBook.Com

bringing data to life

What’s in a constructor?

A big part of the constructor’s job is establishing the properties of an
object, along with their initial values. To create a property within a
constructor, you set the property using a JavaScript keyword called this.
The this keyword assigns ownership of the property to the object, and
also sets its initial value at the same time. The word literally does what
it means—you’re creating a property that belongs to “this” object, as
opposed to just being a local variable within the constructor.

aTowbhhnjaeoetrcttmdhaiipsslrtvokianpergeyiurwaitbsohylreed.fs riasonm function Invitation(who, what, when, where) { Caalsownaasrytesrucocabtpjoeitrcsatliaznraeemd,es.
this.who = who;

this.what = what; The constructor
this.when = when; taorgnuemwenptrsopaerretaiesss.igned
this.where = where;

} Ttohgeetcohnesrtrjuuscttolrikeis put
any
other function.

Object properties are created and initialized in a constructor by using The this keyword is
object notation (the dot operator) and the this keyword. Without the the key to creating
this keyword, the constructor would not know that you're creating object properties
object properties. The result of this constructor is the creation of four inside a constructor.
properties, which are assigned the four values passed as arguments into
the constructor.

Write a constructor for a Blog object that creates and initializes
properties for the date and body text of a blog entry.

you are here 4   403

Download at WoweBook.Com

make it work

The constructor Write a constructor for a Blog object that creates and initializes
is named the properties for the date and body text of a blog entry.
same as the
object. function Blog(body, date) { The body text and date
this.body = body; are passed into the
this.date = date; constructor as arguments.

The this keyword } The properties are
references initialized using
properties of constructor arguments.
the object.

Bringing blog objects to life

The Blog object is certainly shaping up but it hasn’t actually been created Handwritten
yet. As good as it may seem in theory, it’s still just a hypothesis yet to be blog entry.
proven. Remember that the constructor establishes the design of an object
but none are physically created until you use the new operator, which then
builds the object by calling the constructor. So let’s go ahead and create a
real live Blog object.

JavaScript waFvwoalwliola.whbelaaedloffnoigrrswtdliotawbhns.tlcohoaemd/eaxbtoaomhkptslt/ephs,:f/j/s/. 08/14/2008 cube I ordered. It’s a real
Blog object. Got the new
pearl.

var blogEntry = new Blog("Got the new cube I ordered...", "08/14/2008");

Blog The Blog() function Blog(body, date) {
tcooncsrterautcetotrhies called ...
"Got the new object.
cube I ordered. }
It’s a real pearl."
"08/14/2008" Tishceroebatjeecdt.

404   Chapter 9

Download at WoweBook.Com

bringing data to life

Q: I’m confused about object creation. object’s properties, so without a constructor Q: What exactly is this?
you wouldn’t have any properties. And A: this is a JavaScript keyword used
Does the new operator create an object without any properties, you wouldn’t have a
or does the constructor? very meaningful object. to refer to an object. More specifically,
this references an object from within
A: Both! The new operator is responsible There is an exception to this rule about that same object. Yeah, that sounds pretty
constructors, and it applies when creating weird, and slightly schizophrenic. But it
for setting the object creation in motion, a purely organizational object consisting makes sense once you wrap your brain
and a big part of its job is to make sure of a collection of methods that don’t act on around it. To look at it in real world terms,
the constructor gets called. Just calling a object properties. In this case, it’s technically think about what would happen if you lost
constructor like a function without using possible to do without a constructor. But your watch and someone found it in a room
keep in mind that such an object isn’t exactly full of people. When they hold the watch up,
the new operator would not create an a shining example of good object-oriented you would probably yell, "It’s my watch!" You
programming practices because it’s really used the word "my" to refer to yourself. More
object, and using the new operator with no just a collection of related functions. Even so, importantly, the word "my" is used to clarify
constructor would be meaningless. JavaScript itself employs an organizational that you are the owner of the watch. this
object for grouping together math related works exactly the same way—it implies
Q: Does every custom object require a tasks, as you learn later in the chapter. object ownership. So this.date

constructor? means that the date property belongs to
the object in which the code appears.
A: Yes. The reason is because the

constructor is responsible for creating the

08/14/2008 cube I ordered. It’s a real Create an array of Blog objects in a variable named blog that
Got the new is initialized to the blog entries in the YouCube blog. Feel free to
pearl. just write the first few words of body text in each entry.
var blog =
08/19/2008 course, now [
IS’omlvbeodrtehdeannedwshcoubpepibngutfoorf a new one.
];
08/16/2008
Managed to get a headache toiling over

the new cube.
Gotta nap.

08/21/2008 for sale online. Yikes!
Found a 7x7x7 cube beast.
That one could be a

you are here 4   405

Download at WoweBook.Com

sharpen solution

08/14/2008 cube I ordered. It’s a real Create an array of Blog objects in a variable named blog that
Got the new is initialized to the blog entries in the YouCube blog. Feel free to
pearl. just write the first few words of body text in each entry.

08/19/2008 course, now var blog =
IS’omlvbeodrtehdeannedwshcoubpepibngutfoorf a new one.
[ new Blog("Got the new cube I ordered...", "08/14/2008"),
08/16/2008 get a headache toiling over new Blog("Solved the new cube but of course...", "08/19/2008"),
Managed to new Blog("Managed to get a headache toiling...", "08/16/2008"),
the new cube. new Blog("Found a 7x7x7 cube for sale...", "08/21/2008") ];
Gotta nap.
oaEwsancahbBobldoloygg otebenjxtetrctyaniwsditcdhraetiattes.ed
08/21/2008
Found a 7x7x7 cube for sale online. Yikes!
That one could be a beast.

YouCube 1.0 The data stored in
each Blog object is
Combining the array of Blog objects with some JavaScript code for neatly displayed on
displaying the blog data yields an initial version of YouCube. Ruby the YouCube page.
knows her work is not done, but the blog is up and running, and she’s
happy with the early results.

I like how the Blog object
combines the blog date and
body text in YouCube.

406   Chapter 9 Let’s take a peek at the code required to bring the Blog objects to life
and make YouCube 1.0 a reality...

Download at WoweBook.Com

bringing data to life

YouCube Up Close

<html>

<head>
<title>YouCube - The Blog for Cube Puzzlers</title>

<script type="text/javascript"> The Blog() constructor creates
// Blog object constructor the two blog properties.
function Blog(body, date) {
// Assign the properties The array of
this.body = body; Blog objects.
this.date = date;
}

// Global array of blog entries
Ttdhrheaew"ssbhlotowgh"Be ldbovligvoa(g)ornefnubttnlhrceoitegispoantg=oe.[ new Blog("Got the new cube I ordered..", "08/14/2008"),
new Blog("Solved the new cube but of course...", "08/19/2008"), ];
new Blog("Managed to get a headache toiling...", "08/16/2008"),
new Blog("Found a 7x7x7 cube for sale online...", "08/21/2008")

// Show the list of blog entries
function showBlog(numEntries) {
// Adjust the number of entries to show the full blog, if necessary
if (!numEntries)
numEntries = blog.length;
// Show the blog entries ssIfhhootwwheawlalnsuonmf’tbtephraesosefendtbrlaoisegsa.enntarrigeusmteont,
var i = 0, blogText = "";
while (i < blog.length && i < numEntries) {
// Use a gray background for every other blog entry
if (i % 2 == 0)
blogText += "<p style=’background-color:#EEEEEE’>";
else the blog
blogText += "<p>"; Alternate the background color of
entries so they’re easier to read.
// Generate the formatted blog HTML code
blogText += "<strong>" + blog[i].date + "</strong><br />" + blog[i].body + "</p>";

i++; tbShleoetg“tebhnlotegrf"yodrcimovd.atetteod
}

// Set the blog HTML code on the page
document.getElementById("blog").innerHTML = blogText;
}
</script>
</head>

<body onload="showBlog(5);"> The “blog" div, which starts out empty but
<h3>YouCube - The Blog for Cube Puzzlers</h3> gets filled with formatted blog data.
<img src="cube.png" alt="YouCube" />

<div id="blog"></div>

<input type="button" id="showall" value="Show All Blog Entries" onclick="showBlog();" />

</body>

</html> Show all blog entries when
the button is clicked.

you are here 4   407

Download at WoweBook.Com

why, why, why

Q: Why is the Show All Blog Entries Q: Why is innerHTML used to convenience in this case, and simplifies the
YouCube code considerably.
button necessary in YouCube? show the blog entries instead of DOM
methods? Q: Why doesn’t the Blog object have
A: In the current state of the blog, the
A: Although DOM methods are certainly any methods?
button is not necessary at all since there are
only four blog entries total. But as the blog preferred in terms of web standards A: Ambition, that’s good! The truth is that
grows, it becomes increasingly important compliance, they are fairly unwieldy
to limit the number of entries shown initially when it comes to dynamically generating there are plenty of other aspects of YouCube
on the main YouCube page to keep from highly formatted HTML code. The reason to work on before Blog methods become
overwhelming visitors. So the blog code is because every container tag such as a true priority. But don’t worry, methods are
defaults to only showing the first five entries. <p> and <strong> has to be created definitely part of the long-range plan for
The Show All Blog Entries button overrides as a parent with child nodes for their YouCube. Methods are an important part of
this default by displaying all blog entries. content. innerHTML is a tremendous any well-designed object, and the Blog
object is no different.

A disorderly blog The order of blog
entries should be
YouCube 1.0 looks good but it isn’t without its flaws. Ruby has noticed that most recent first.
the blog entries are in the wrong order—they really should appear with
the most recent post first. Right now they are displayed in whatever order
they are stored, which we can’t count on being chronological.

I just realized that I don’t
always write the blog
entries in chronological
order...that’s a problem!

Users expect blog
the topmost
entry to be the
most recent.

408   Chapter 9

Download at WoweBook.Com

bringing data to life

The need for sorting

Ruby’s solution to the blog ordering problem is to sort the blog array by

date. Since JavaScript supports looping and comparisons, it should be

possible to loop through the blog entries, compare dates to each other, and oeSnnwetaripisetsmhsoeirnseceertetwchoeenbtsl.eocgond

sort them into reverse chronological order (most recent posts first).
Blog

"Got the new cube Blog Blog This blog entry should
I ordered. It’s a appear first since it’s
1 Loop through the real pearl." "Solved the new the most recent.
"08/14/2008" cube but of

course, now..."

blog array. "08/19/2008" "Managed to get a

2 Compare the date of each Blog object headache toiling Blog
over the new..."
to the next one.
"08/16/2008"

3 I f the next blog entry is more recent than the current "Found a 7x7x7
entry, swap them. cube for sale

online. Yikes..."

"08/21/2008"

This blog sorting solution has some merit and sounds like it could work,
assuming we can work out the details of comparing blog dates.

Wait a minute! If dates are stored as
strings, how can you compare them to
see which one is most recent?

A date stored in a string isn’t really a date. you are here 4   409
Ruby’s blog sorting strategy has run into a serious snag due to the fact that
a date stored as a string has no concept of time. In other words, there is
no way to compare the strings "08/14/2008" to "08/19/2008" to
see which one is more recent because they are just strings. Although it
is possible to compare strings, such comparisons don’t understand the
specific format of a date, and therefore aren’t able to compare the month,
day, and year components of a date when carrying out the comparison.
So before we can think seriously about sorting the blog entries by date, we
first need to rethink the manner in which dates are stored in the blog.

Download at WoweBook.Com

have you seen my date

A JavaScript object for dating The date of the
first blog entry.
What Ruby needs is the ability to store a date in such a way that it can be
compared to other dates. In other words, the date needs to understand
that it is a date, and behave accordingly. Wait a minute, that sounds a lot
like an object! And as it turns out, JavaScript offers a built-in Date object
that could very well be what Ruby needs.

Date

setMonth() getDate()

Methods that August 14th, 2008 getDay() Methods that
set date data. get date data.

setYear()

getFullYear()

The built-in Date The Date object represents a specific moment in time, down to the
object represents millisecond, and is a standard part of JavaScript. Although the Date
a moment in time. object certainly uses properties internally, they are invisible to you, the user
of the object. You work with the Date object purely through its methods.

Similar to the Blog object, you create a Date object using the new

operator. Here’s an example of creating a Date object that represents the

ScortbeojaertcetetdihneDaantevwearlyiable. current date and time:

var now = new Date();

Within the Date Create a Date object TrcehuprisrreensneetwntdDsaatttehe/etoibmjee.ct
using the new operator.

object, time is This Date object is created and initialized with the current date and
expressed in time. Notice that the syntax for creating a Date object is a lot like calling
milliseconds. a function or method, and that’s because you’re actually calling the
constructor of the Date object. You can pass the Date() constructor a
string argument to specify a date other than the present. For example, this

Date object represents the date of the first YouCube blog entry:

The date is passed to var blogDate = new Date("08/14/2008");
the constructor as a
string of text.

410   Chapter 9

Download at WoweBook.Com

bringing data to life

Calculating time

One of the most powerful features of objects is how they inherently know
how to manipulate themselves. For example, think about how tricky it
would be to calculate the number of days between two dates on your own.
You’d have to somehow convert a date into a number of days from some
known reference, making sure to factor in leap years. Or you could just let
the Date object do the work for you...check out this function that does
the heavy lifting with a couple of Date objects:

The function accepts two htCooounsrevsecrtotonddfsratoyoms. milliseconds
Date objects as arguments. minutes to
Whew!

function getDaysBetween(date1, date2) {

var daysBetween = (date2 - date1) / (1000 * 60 * 60 * 24);

return Math.round(daysBetween);

} Stdhiomiespsliesaltbl uhttehecpoowdwoeerrktf!hual,t

torRafeoctuktunlrhdeneloaiMtft.fea..rtrthoihuneonbdtrjh(ee)escuticsl,thawaaphmntidceehtrh.woed

getDaysBetween(date1, date2); This function reveals the power of the Date object in a simple piece of
code—a subtraction. All of the complexity associated with calculating
the difference between two dates is conveniently buried inside the Date
object. Our only concern is the result of the subtraction, which is the
number of milliseconds between the two dates. Convert milliseconds to
days, round off the result, and we have a handy little function that can be
reused any time we need to know the difference between two dates.

Create two Date objects for the first two YouCube blog entries. Then call the
getDaysBetween() function, passing in the two Date objects, and displaying
the result in an alert box.

you are here 4   411

Download at WoweBook.Com

exercise solution

Create two Date objects for the first two YouCube blog entries. Then call the
getDaysBetween() function, passing in the two Date objects, and displaying
the result in an alert box.

Create Date objects for
the two blog entry dates.

var blogDate1 = new Date("08/14/2008");
var blogDate2 = new Date("08/19/2008");
alert("The dates are separated by " + getDaysBetween(blogDate1, blogDate2) + " days.");

Trdehitfefufrernuensncttcheio.en toPobajsteschtteshfeaustncwatorigoDunm.aetnets

Rethinking blog dates Date

While it’s great that JavaScript offers a Date object that makes it possible
to manipulate dates intelligently, the YouCube Blog object currently still
stores dates as strings, not Date objects. In order to take advantage of the
features made available by the Date object, we need to change the blog
so that the blog dates are Date objects.

Blog

The date property of the August 14th, 2008
Blog object needs to be
"Got the new converted from a string
cube I ordered. to a Date object.
It’s a real pearl."
"08/14/2008"

The question is, can the date property of the Blog object store a Date
object instead of a string?

412   Chapter 9

Download at WoweBook.Com

bringing data to life

An object within an object

The Blog object is a good example of how objects must often contain The string literal
other objects. The two properties of the Blog object are actually already automatically creates
objects themselves—both properties are String objects. The String a String object.
objects don’t really look like objects because they are created as object
literals by simply quoting a string of text. Date objects aren’t as flexible, The Blog object is created
and must be created using the new operator. using the new operator.

To create a blog date property as a Date object, we must use the new
operator to create a new Date while creating the Blog object. If this
sounds nightmarish, maybe some code will ease the fear.

var blogEntry = new Blog("Nothing going on but the weather.",

new Date("10/31/2008")); ApaalsDsosaeutdseininogtbotjehtcetheniesBwclorogep(ae)treacdtoonarstn. dructor,
This code reveals how a YouCube blog entry is now created as an object

that contains two other objects (a String object and a Date object).

Of course, we still need to build an array of Blog objects in order to The new operator
successfully represent all of the YouCube blog entries.

String body property. Blog creates objects
"Got the new with the help of
cube I ordered. Date "Got the new cube constructors.
It’s a real pearl." I ordered. It’s a
real pearl."

August 14th, August 14th, 2008
2008

date property.

Rewrite the code to create an array of YouCube Blog objects
where each date is now a Date object. Feel free to shorten the
body text.

you are here 4   413

Download at WoweBook.Com

sharpen solution

Each blog entry is still Rewrite the code to create an array of YouCube Blog objects
created as a Blog object. where each date is now a Date object. Feel free to shorten the
body text.

var blog = [ new Blog("Got the new cube I ordered...", new Date("08/14/2008")),
new Blog("Solved the new cube but of course...", new Date("08/19/2008")),
new Blog("Managed to get a headache toiling...", new Date("08/16/2008")),
new Blog("Found a 7x7x7 cube for sale...", new Date("08/21/2008")) ];

String literals work fine for the The date for aeaDchatBe loogbjoebctje. ct
body text of each blog entry. is created as

Q: Why is the date in a Date object stored in milliseconds? tiniest fractions of time. How about a millisecond? So instead of
A: First off, understand that the Date object represents all those different units of time, you now have 1,218,702,551,000
milliseconds. Yeah, that’s a whole bunch of milliseconds but big
an instant in time. If you could click the Pause button on the numbers aren’t a problem for JavaScript.
universe, you’d have a frozen moment in time. But you wouldn’t
have any way to tell people when the moment occurred without Q: Do I have to worry about converting milliseconds when
some kind of reference. So you decide on January 1, 1970 as the
arbitrary reference point for your moment in time. Now you need a using the Date object?
measurement from this offset. Maybe it’s 38 years, 8 months, 14
days, 3 hours, 29 minutes, and 11 seconds. But that’s a cumbersome A: It depends. The Date object includes several methods for
way to keep track of a time offset. It’s much easier to stick with a
single unit of measurement, one that is capable of representing the extracting meaningful parts of a date that avoid dealing directly with
milliseconds. However, if you need to deal with a difference between
two dates, then milliseconds will almost certainly enter the picture.

 The standard JavaScript Date objects represents an  The Date object is smart enough to know how to
instant in time, expressed in milliseconds. manipulate dates mathematically, as well as compare
dates to each other.
 The Date object includes several methods for
accessing the different pieces and parts of a date and  Like most objects other than String, you create a
time. Date object using the new operator.

414   Chapter 9

Download at WoweBook.Com


Click to View FlipBook Version