A Brain-Friendly Guide

Head First

JavaScript

Improve your user experience with web page interactivity

Load important 1 JavaScript concepts directly into your brain

Slice and Whip up working dice HTML JavaScript with help from code in a snap the DOM

Bend your mind around Stop fearing event dozens of puzzles and handling——it won’t exercises hurt a bit

O’REILLY® Michael Morrison

Head First JavaScript

by Michael Morrison

Copyright © 2008 O’Reilly Media, Inc. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly Media books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (safari.oreilly.com). For more information, contact our corporate/institutional sales department: (800) 998-9938 or corporate@oreilly.com.

Series Creators: Kathy Sierra, Bert Bates Series Editor: Brett D. McLaughlin Design Editor: Louise Barr Cover Designers: Louise Barr, Steve Fehler Production Editor: Sanders Kleinfeld Proofreader: Colleen Gorman Indexer: Julie Hawks…but my koi fish

couldn’t care less.

Page Viewers: Masheed Morrison (wife), family, and pet fish

Printing History:

December 2007: First Edition.

My family knows how to celebrate a book release…

The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. The Head First series designations, Head First JavaScript, and related trade dress are trademarks of O’Reilly Media, Inc.

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a trademark claim, the designations have been printed in caps or initial caps.

While every precaution has been taken in the preparation of this book, the publisher and the author assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

No rocks, stick figures, cube puzzles, or macho moviegoers were harmed in the making of this book. Just me, but I can handle it…I’m wiry.

TM TM This book uses RepKover™, a durable and fl exible lay-fl at binding.

ISBN-10: 0-596-52774-8 ISBN-13: 978-0-596-52774-7 [M]

table of contents

Table of Contents (Summary)

Introxxiii
1the interactive web: Reacting to the Virtual World1
2storing data: Everything Has Its Place33
3exploring the client: Browser Spelunking85
4decision making: If There’s a Fork in the Road, Take It135
5looping: At the Risk of Repeating Myself189
6functions: Reduce, Reuse, Recycle243
7forms and validation: Getting the User to Tell All289
8wrangling the page: Slicing and Dicing HTML with the DOM343
9bringing data to life: Objects as Frankendata393
10creating custom objects: Having It Your Way with Custom Objects449
11kill bugs dead: Good Scripts Gone Wrong485
12dynamic data: Touchy-Feely Web Applications537

Table of Contents (the real thing)

Intro Your brain on JavaScript. You’re sitting around trying to learn something, but your brain keeps telling you all that learning isn’t important. Your brain’s saying, “Better leave room for more important things, like which wild animals to avoid and whether naked water skiing is a bad idea.” So how do you trick your brain into thinking that your life really depends on learning JavaScript?

Who is this book for? xxiv We know what you’re thinking xxv Metacognition xxvii Bend your brain into submission xxix Read me xxx The technical review team xxxii Acknowledgments xxxiii

ix

table of contents

the interactive web

Reacting to the Virtual World

Tired of thinking of the Web in terms of passive pages? Been there, done that. They’re called books. And they’re good for reading, learning… 1 lots of good things. But they’re not interactive. And neither is the Web without a little help from JavaScript. Sure, you can submit a form and maybe do a trick here and there with some crafty HTML and CSS coding, but you’re really just playing Weekend at Bernie’s propping up a lifeless web page. Real live interactivity requires a bit more smarts and a little more work… but it has a much bigger payoff.

(Online) people have needs 2 Like talking to a brick wall… nothing happens 3 But JavaScript talks back 4 Lights, camera, interaction! 6 Use the

x

table of contents

storing data

Everything Has Its Place

In the real world, people often overlook the importance of

having a place to store all their stuff. Not so in JavaScript. You simply 2 don’t have the luxury of walk-in closets and three-car garages. In JavaScript, everything has its place, and it’s your job to make sure of it. The issue is data—how to represent it, how to store it, and how to find it once you’ve put it somewhere. As a JavaScript storage specialist, you’ll be able to take a cluttered room of JavaScript data and impose your will on it with a flurry of virtual labels and storage bins.

Your scripts can store data 34 Scripts think in data types 35 Constants stay the SAME, variables can CHANGE 40 Variables start out without a value 44 Initialize a variable with “=” 45 Constants are resistant to change 46 What’s in a name? 50 Legal and illegal variable and constant names 51 Variable names often use CamelCase 52 Plan the Duncan’s Donuts web page 56 A first take at the donut calculations 58 Initialize your data…or else 61 NaN is NOT a number 62 You can add more than numbers 64 parseInt() and parseFloat() convert text to a number 65 Why are extra donuts being ordered? 66 Duncan discovers donut espionage 70 Use getElementById() to grab form data 71 Validate the web form’s data 72 Strive for intuitive user input 77

xi

table of contents

exploring the client

Browser Spelunking

Sometimes JavaScript needs to know what’s going on in the world around it. Your scripts may begin as code in web pages but they ultimately 3 live in a world created by the browser, or client. Smart scripts often need to know more about the world they live in, in which case they can communicate with the browser to find out more about it. Whether it’s finding out the screen size or accessing the browser’s snooze button, scripts have an awful lot to gain by cultivating their browser relationship.

Clients, servers, and JavaScript 86 What can a browser do for you? 88 The iRock needs to be more responsive 90 Timers connect action to elapsed time 92 Breaking down a timer 93 Set a timer with setTimeout() 94 A closer look: the setTimeout() function 95 Multiple size screens, multiple complaints 99 Use the document object to get the client window’s width 100 Use document object properties to set the client window width 101 Set the height and width of the iRock image 102 The iRock should be sized to the page 103 onresize is triggered when the browser’s resized 107 The onresize event resizes the rock 108 Have we met? Recognizing the user 110 Every script has a life cycle 111 Cookies outlive your script’s life cycle 112 Cookies have a name and store a value… and can expire 117 Your JavaScript can live OUTSIDE your web page 119 Greet the user with a cookie 120 greetUser() is cookie-powered now 121 Don’t forget to set the cookie, too 122 Cookies affect browser security 124 A world without cookies 126 Talk to the users… it’s better than nothing 129

xii

table of contents

decision making

If There’s a Fork in the Road, Take It

Life is all about making decisions. Stop or go, shake or bake, plea bargain or go to trial… without the ability to make decisions, nothing would ever get done. It works 4 the same in JavaScript—decisions allow scripts to decide between different possible outcomes. Decision-making drives the “story” of your scripts, and even the most mundane scripts involve a story of some sort. Do you trust what the user entered and book her a trip on a Sasquatch expedition or do you double-check that maybe she really just wanted to ride a bus to Saskatchewan? The choice is yours to make!

Lucky contestant, come on down! 136 “if” this is true… then do something 138 An if statement evaluates a condition… and then takes action 139 Use if to choose between two things 141 You can make multiple decisions with if 142 Adding an else to your if statement 143 Variables drive the story 146 But part of the story is missing 147 Compounding your JavaScript efforts 148 Tiered decision making with if/else 154 An if can go inside another if 155 Your functions control your pages 157 Pseudocode lets you map out your adventure 158 Stick figure inequality 162 != Psst, I’ve got nothing to tell you… 163 Crafting decisions with comparison operators 164 Comments, placeholders, and documentation 166 Comments in JavaScript start with // 167 Scope and context: Where data lives 169 Check your adventure variable score 170 Where does my data live? 171 Choice of five 174 Nesting if/else can get complicated 175 Switch statements have multiple cases 177 Inside the switch statement 178 A switchy stick figure adventure: test drive 183

xiii

table of contents looping 5 WithoutAt the Risk of Repeating Myself Some say repetition is the spice of life. interesting is certainly exciting, but it’s the little repetitive things that really make it possible to get through the day. Compulsive hand sanitizing, a nervous tick, clicking Reply To All to every freaking message you receive! Okay, maybe repetition isn’t always such a great thing in the real world. However, it can be extremely handy in the world of JavaScript. You’d be surprised how often you need a script to loopsSure, doing something new and run a piece of code several times., you’d be wasting a lot of time cutting and pasting a bunch of wasteful code.
xivX marks the spot Déjà vu all over again…for loops Treasure hunting with a for loop Dissect the for loop Mandango: a macho movie seat finder First check seat availability Looping, HTML, and seat availability Movie seats as variables Arrays collect multiple pieces of data Array values are stored with keys From JavaScript to HTML Visualizing Mandango seats Test drive: the solo seat finder Too much of a good thing: endless loops Loops always need an exit condition (or two!) A “break” in the action Boolean operator logic uncovered Looping for just a “while”…until a condition is met Breaking down the while loop Use the right loop for the job Movie seat data modeling An array of an array: two-dimensional arrays Two keys to access 2-D array data Mandango in 2-D An entire theater of manly seats190 191 192 193 194 195 196 197 198 199 203 204 209 210 211 212 218 222 223 225 231 232 233 235 238

table of contents

functions

Reduce, Reuse, Recycle

If there was an environmental movement within JavaScript, it would be led by functions. Functions allow you to make JavaScript code 6 more efficient, and yes, more reusable. Functions are also task-oriented, good at code organization, and excellent problem solvers. Sounds like the makings of a good resume! In reality, all but the simplest of scripts stand to benefit from a functional reorganization. While it’s hard to put a number on the carbon footprint of the average function, let’s just say they do their part in making scripts as eco-friendly as possible.

The mother of all problems 244 Functions as problem solvers 246 The nuts and bolts of a function 247 A function you’ve already met 248 Building a better thermostat 251 Passing information to functions 252 Function arguments as data 253 Functions eliminate duplicate code 254 Creating a seat setter function 257 The setSeat() function 259 The significance of feedback 261 Returning data from functions 262 Many happy return values 263 Getting the status of a seat 267 Showing the seat status 268 You can link the function to an image 269 Repetitive code is never a good thing 270 Separating functionality from content 271 Functions are just data 272 Calling or referencing your functions 273 Events, callbacks, and HTML attributes 277 Wiring events using function references 278 Function literals to the rescue 279 Where’s the wiring? 280 A shell of an HTML page 283

xv

table of contents

forms and validation

Getting the User to Tell All

You don’t have to be suave or sneaky to successfully get

information from users with JavaScript. But you do have to be 7 careful. Humans have this strange tendency to make mistakes, which means you can’t always count on the data provided in online forms being accurate. Enter JavaScript. By passing form data through the right JavaScript code as it is being entered, you can make web applications much more reliable, and also take some load off of the server. We need to save that precious bandwidth for important things like stunt videos and cute pet pictures.

The Bannerocity HTML form 291 When HTML is not enough 292 Accessing form data 293 Form fields follow a chain of events 295 Losing focus with onblur 296 Alert box validation 297 Validate fields to make sure you have “not nothing” 301 Validation without aggravating alert boxes 302 A more subtle non-empty validator 303 Size matters… 305 Validating the length of data 306 Validating a ZIP code 311 Validating a date 316 Regular expressions aren’t “regular” 318 Regular expressions define patterns to match 319 Metacharacters represent more than one literal character 321 Drilling into regular expressions: quantifiers 322 Validating data with regular expressions 326 Matching mins and maxes 329 Eliminating three-digit years with this…or that 331 Leave nothing to chance 332 Can you hear me now? Phone number validation 333 You’ve got mail: validating email 334 The exception is the rule 335 Matching optional characters from a set 336 Constructing an email validator 337

xvi

table of contents

wrangling the page

Slicing and Dicing HTML with the DOM

Taking control of web page content with JavaScript is a lot like baking. Well, without the mess… and unfortunately, also without the edible 8 reward afterward. However; you get full access to the HTML ingredients that go into a web page, and more importantly, you have the ability to alter the recipe of the page. So JavaScript makes it possible to manipulate the HTML code within a web page to your heart’s desire, which opens up all kinds of interesting opportunities all made possible by a collection of standard objects called the DOM (Document Object Model).

Functional but clumsy…interface matters 344 Describing scenes without alert boxes 345 Accessing HTML elements 347 Getting in touch with your inner HTML 348 Seeing the forest and the trees: the Document Object Model (DOM) 353 Your page is a collection of DOM nodes 354 Climbing the DOM tree with properties 357 Changing node text with the DOM 360 Standards compliant adventuring 365 Designing better options 367 Rethinking node text replacement 368 Replacing node text with a function 369 Dynamic options are a good thing 370 Interactive options are even better 371 A matter of style: CSS and DOM 372 Swapping style classes 373 Classy options 374 Test drive the stylized adventure options 375 Options gone wrong: the empty button 376 A la carte style tweaking 377 No more bogus options 379 More options, more complexity 380 Tracking the decision tree 382 Building the decision history in HTML 383 Manufacturing HTML code 384 Tracing the adventure story 387

xvii

table of contents

bringing data to life

Objects as Frankendata

JavaScript objects aren’t nearly as gruesome as the good doctor might have you think. But they are interesting in that they combine 9 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…

A JavaScript-powered party 394 Data + actions = object 395 An object owns its data 396 Object member references with a dot 396 Custom objects extend JavaScript 401 Construct your custom objects 402 What’s in a constructor? 403 Bringing blog objects to life 404 The need for sorting 409 A JavaScript object for dating 410 Calculating time 411 Rethinking blog dates 412 An object within an object 413 Converting objects to text 416 Accessing pieces and parts of a date 417 Arrays as objects 420 Custom sorting an array 421 Sorting made simple with function literals 422 Searching the blog array 425 Searching within strings: indexOf( ) 427 Searching the blog array 428 Searching works now, too! 431 The Math object is an organizational object 434 Generate random numbers with Math.random 436 Turn a function into a method 441 Unveiling the shiny new blog object 442 What do objects really offer YouCube? 443

xviii

table of contents

creating custom objects

Having It Your Way with Custom Objects

If it was only that easy, we’d surely have it made. JavaScript doesn’t have a money-back guarantee, but you can definitely have it your way. Custom objects 10 are the JavaScript equivalent of a decaf triple shot grande extra hot no whip extra drizzle no foam marble mocha macchiato. That is one custom cup of coffee! And with custom JavaScript objects, you can brew up some code that does exactly what you want, while taking advantage of the benefits of properties and methods. The end result is reusable code that effectively extends the JavaScript language…just for you!

Revisiting the YouCube Blog methods 450 Method overload 451 Classes vs. instances 452 Instances are created from classes 453 Access an instance’s properties with “this” 454 Own once, run many: class-owned methods 455 Use prototype to work at a class-level 456 Classes, prototypes, and YouCube 457 Class properties are shared, too 462 Creating class properties 463 Signed and delivered 465 A date formatting method 468 Extending standard objects 469 Custom date object = better YouCube 470 A class can have its own method 471 Examine the sort comparison function 473 Calling a class method Calling a class method 474 474 A picture is worth a thousand words A picture is worth a thousand words 475 475 Incorporating images into YouCube 476 Adding imagery to YouCube 478 An object-powered YouCube 480

xix

table of contents

kill bugs dead

Good Scripts Gone Wrong

Even the best laid JavaScript plans sometimes fail. When this happens, and it will, your job is not to panic. The best JavaScript developers are not 11 the ones who never create bugs-those people are called liars. No, the best JavaScript developers are those who are able to successfully hunt down and eradicate the bugs they create. More importantly, top notch JavaScript bug exterminators develop good coding habits that minimize the sneakiest and nastiest of bugs. A little prevention can go a long way. But bugs happen, and you’ll need an arsenal of weapons to combat them…

Real-world debugging 486 The case of the buggy IQ calculator 487 Try different browsers 488 Debugging on easy street 491 Variables gone wild undefined 495 Crunching the intelligence numbers 497 The case of the radio call-in bugs 498 Opening up the investigation 499 A question of syntax validation (Bug #1) 500 Careful with those strings 501 Quotes, apostrophes, and consistency 502 When a quote isn’t a quote, use escape characters 503 Undefined isn’t just for variables (Bug #2) 504 Everyone’s a winner (Bug #3) 506 Alert box debugging 507 Watching variables with alert 508 Bad logic is legal but buggy 510 Everyone’s a loser! (Bug #4) 514 Overwhelmed by annoying alerts 515 Build a custom console for debugging 517 The peskiest errors of all: runtime 524 The JavaScript bug trifecta 525 Comments as temporary code disablers 528 The dangers of shadowy variables 530

xx

table of contents

dynamic data

Touchy-Feely Web Applications

The modern Web is a very responsive place where pages

are expected to react to the user’s every whim. Or at least that’s 12 the dream of many web users and developers. JavaScript plays a vital role in this dream through a programming technique known as Ajax that provides a mechanism for dramatically changing the “feel” of web pages. With Ajax, web pages act much more like full-blown applications since they are able to quickly load and save data dynamically while responding to the user in real time without any page refreshes or browser trickery.

Yearning for dynamic data 538 A data-driven YouCube 539 Ajax is all about communication 541 XML lets you tag YOUR data YOUR way 543 XML + HTML = XHTML 545 XML and the YouCube blog data 547 Injecting YouCube with Ajax 550 JavaScript to the Ajax rescue: XMLHttpRequest 552 Get or Post? A request with XMLHttpRequest 555 Making sense of an Ajax request 559 Interactive pages start with a request object 563 Call me when you’re done 564 Handling a response…seamlessly 565 The DOM to the rescue 566 YouCube is driven by its data 571 Dysfunctional buttons 573 The buttons need data 574 Time-saving web-based blog additions 577 Writing blog data 578 PHP has needs, too 581 Feeding data to the PHP script 582 Getting it up: Posting blog data to the server 585 Making YouCube more, uh, usable 590 Auto-fill fields for your users 591 Repetitive task? How about a function? 592

xxi

Advance Praise for Head First JavaScript

“So practical and useful, and so well explained. This book does a great job of introducing a complete newbie to JavaScript, and it’s another testament to Head First’s teaching style. Out of the other JavaScript books, Head First JavaSeript is great for learning, compared to other reference books the size of a phone book.” — Alex Lee, Student, University of Houston

“An excellent choice for the beginning JavaScript developer.” — Fletcher Moore, Web Developer & Designer, Georgia Institute of Technology

“Yet another great book in the classic ‘Head First’ style.” — TW Scannell

“JavaScript has long been the client-side engine that drives pages on the Web, but it has also long been misunderstood and misused. With Head First JavaScript, Michael Morrison gives a straightforward and easy-to-understand introduction of this language, removing any misunderstanding that ever existed and showing how to most effectively use it to enhance your web pages.” — Anthony T. Holdener III, Web applications developer, and the author of Ajax: The Definitive Guide.

“A web page has three parts—content (HTML), appearance (CSS), and behaviour (JavaScript). Head First HTML introduced the first two, and this book uses the same fun but practical approach to introduce JavaScript. The fun way in which this book introduces JavaScript and the many ways in which it reinforces the information so that you will not forget it makes this a perfect book for beginners to use to

start them on the road to making their web pages interactive.”

— Stephen Chapman, Owner Felgall Pty Ltd., JavaScript editor, about.com

“This is the book I’ve been looking for to recommend to my readers. It is simple enough for complete beginners but includes enough depth to be useful to more advanced users. And it makes the process of

learning fun. This might just be the only JavaScript book you ever need.”

-Julie L Baumler, JavaScript Editor, BellaOnline.com

If you haven’t read this book yet, and

youre new to JavaScript, we recommed that

Praise for Head First HTML with CSS & XHTML you do.

“Eric and Elisabeth Freeman clearly know their stufE As the Internet becomes more complex, inspired construction of web pages becomes increasingly critical. Elegant design is at the core of every chapter here, each concept conveyed with equal doses of pragmatism and wit.” — Ken Goldstein, Executive Vice President & Managing Director, Disney Online

“The Web would be a much better place if every HTML author started off by reading this book.” — L. David Baron, Technical Lead, Layout & CSS, Mozilla Corporation http://dbaron.org/

“Tve been writing HTML and CSS for ten years now, and what used to be a long trial and error learning process has now been reduced neatly into an engaging paperback. HTML used to be something you could just hack away at until things looked okay on screen, but with the advent of web standards and the movement towards accessibility, sloppy coding practice is not acceptable anymore… from a business standpoint or a social responsibility standpoint. Head First HTML with CSS XHTML teaches you how to do things right from the beginning without making the whole process seem overwhelming. HTML, when properly explained, is no more complicated than plain English, and the Freemans do an excellent job of keeping every concept at eye-level.” — Mike Davidson, President & CEO, Newsvine, Inc.

“Oh, great. You made an XHTML book simple enough a CEO can understand it. What will you do next? Accounting simple enough my developer can understand it? Next thing you know we’ll be collaborating as a team or something.” —Janice Fraser, CEO, Adaptive Path

“This book has humor, and charm, but most importanty; it has heart. I know that sounds ridiculous to say about a technical book, but I really sense that at its core, this book (or at least its authors) really care that the reader learn the material. This comes across in the style, the language, and the techniques. Learning− real understanding and comprehension – on the part of the reader is clearly top most in the minds of the Freemans. And thank you, thank you, thank you, for the book’s strong, and sensible advocacy of standards compliance. It’s great to see an entry level book, that I think will be widely read and studied, campaign so eloquently and persuasively on behalf of the value of standards compliance in web page code. I even found in here a few great arguments I had not thought of – ones I can remember and use when I am asked – as I still am - ‘what’s the deal with compliance and why should we care?’ I’ll have more ammo now! I also liked that the book sprinkles in some basics about the mechanics of actually getting a web page live-FTP, web server basics, file structures, etc.” —Robert Neer, Director of Product Development, Movies.com

Praise for Head First HTML with CSS & XHTML

“Freeman’s Head First HTML with CSS XHTML is a most entertaining book for learning how to build a great web page. It not only covers everything you need to know about HTML, CSS, and XHTML, it also excels in explaining everything in layman’s terms with a lot of great examples. I found the book truly enjoyable to read, and I learned something new!” — Newton Lee, Editor-in-Chief, ACM Computers in Entertainment, http://www.acmcie.org

“My wife stole the book. She’s never done any web design, so she needed a book like Head First HTML with CSS XH7ML. to take her from beginning to end. She now has a list of web sites she wants to build

  • for our son’s class, our family, .. If I’m lucky, I’ll get the book back when she’s done.” — David Kaminsky, Master Inventor, IBM “Beware. If you’re someone who reads at night before falling asleep, you’ll have to restrict Head Fist HTML with CSS XHTML to daytime reading. This book wakes up your brain.” — Pauline McNamara, Center for New Technologies and Education, Fribourg University, Switzerland

“The information covered in this book is the same material the pros know, but taught in an educational and humorous manner that doesn’t ever make you think the material is impossible to learn or you are out of your element.” —Christopher Schmitt, Author of The CSS Cookbook and Professional CSS, schmitt@christopher.org

“Head First HTML with CSS XHTML is a thoroughly modern introduction to forward-looking practices in Web page markup and presentation. It correctly anticipates readers’ puzzlements and handles them just in time. The highly graphic and incremental approach precisely mimics the best way to learn this stuff: make a small change and see it in the browser to understand what each new item means.” —Danny Goodman, author of Dynamic HTML: The Definitive Guide

Head First JavaScript by Michael Morrison

Copyright © 2008 O’Reilly Media, Inc. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly Media books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (safari.oreillz.com). For more information, contact our corporate/institutional sales department: (800) 998-9938 or corporate@oreilly.cm.

Series Creators: Series Editor: Design Editor: Cover Designers: Production Editor: Proofreader: Indexer: Page Viewers:

Printing History: December 2007: First Edition.

My family knows

how to celebrate

a book release…

Kathy Sierra, Bert Bates Brett D. McLaughlin Louise Barr Louise Barr, Steve Fehler Sanders Kleinfeld Colleen Gorman

..but my koi fish

Julie Hawks

couldn’t care less

Masheed Morrison (wife), family, and pet fish

The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. The Head Fist series designations, Head First JavaScript, and related trade dress are trademarks of O’Reilly Media, Inc.

Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks, Where those designations appear in this book, and O’Reilly Media, Inc., was aware of a trademark claim, the designations have been printed in caps or initial caps.

While every precaution has been taken in the preparation of this book, the publisher and the author assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.

No rocks, stick figures, cube puzzles, or macho moviegoers were harmed in the making of this book. Just me, but I can handle it..‘m wiry

RepKover. This book uses RepKover, a durable and flexible lay-flat binding

ISBN-10:0-596-52774-8 ISBN-13:978-0-596-52774-7

[M]

To the folks at Netscape who, way back in the last century, dreamed that the Web could be much more than a big online book with a bunch of linked pages that don’t do anything. Of course, they also dreamed up that horrific tag..dare to dream, just don’t get too carried away!