<<

6803.book Page 451 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ ■ ■ Debugging JavaScript

In this appendix, I will introduce you to some tricks and tools to debug your JavaScript code. It is very important to get acquainted with debugging tools, as programming consists to a large extent of trying to find out what went wrong a particular time. Some browsers help you with this problem; others make it harder by having their debugging tools hidden away or returning cryptic error messages that confuse more than they help. Some of my favorites include philo- sophical works like “Undefined is not defined” or the MSIE standard “Object doesn’t support this property or method.”

Common JavaScript Mistakes Let’s start with some common mistakes that probably every JavaScript developer has made during his career. Having these in the back of your head when you check a failing script might make it a lot quicker to spot the problem.

Misspellings and Case-Sensitivity Issues The easiest mistakes to spot are misspellings of JavaScript method names or properties. Clas- sics include getElementByTagName() instead of getElementsByTagName(), getElementByID() instead of getElementById() and node.style.colour (for the British English writers). A lot of times the problem could also be case sensitivity, for example, writing keywords in mixed case instead of lowercase.

If( elm.href ) { var url = elm.href; }

There is no keyword called If, but there is one called if. The same problem of case sensi- tivity applies to variable names:

var FamilyGuy = 'Peter'; var FamilyGuyWife = 'Lois'; alert( 'The Griffins:\n'+ familyGuy + ' and ' + FamilyGuyWife );

This will result in an error message stating “familyGuy is not defined”, as there is a variable called FamilyGuy but none called familyGuy. 451 6803.book Page 452 Thursday, June 15, 2006 2:24 PM

452 APPENDIX ■ DEBUGGING JAVASCRIPT

Trying to Access Undefined Variables We talked about it in the first chapter of the book—you define variables either by declaring them with or without an additional var keyword (the latter is necessary to define the scope of the variable).

Stewie = "Son of Peter and Lois"; var Chris = "Older Son of Peter and Lois";

If you try to access a variable that hasn’t been defined yet, you’ll get an error. The alert() in the following script throws an error as Meg is not defined yet.

Peter = "The Family Guy"; Lois = "The Family Guy's Wife"; Brian = "The Dog"; Stewie = "Son of Peter and Lois"; Chris = "Older Son of Peter and Lois"; alert( Meg ); Meg = "The Daughter of Peter and Lois";

This is easy when it is an obvious example like this one, but how about trying to guess where the bug in the following example is?

exampleFamilies.

function getFamilyData( outptID, isTree, familyName ) { var father, mother, child; switch( familyName ) { case 'Griffin': father = "Peter"; mother = "Lois"; child = "Chris"; break; case 'Flintstone': father = "Fred"; mother = "Wilma"; child = "Pebbles"; break; } var out = document.getElementById( outputID ); if( isTree ) { var newUL = document.createElement( 'ul' ); newUL.appendChild( makeLI( father ) ); newUL.appendChild( makeLI( mother ) ); newUL.appendChild( makeLI( child ) ); out.appendChild( newUL ); 6803.book Page 453 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 453

} else { var str = father + ' ' + mother + ' ' + child; out.appendChild( document.createTextNode( str ) ); } } getFamilyData( 'tree', true, 'Griffin' );

Microsoft Internet Explorer tells you that there is an error in line 23—“‘outputID’ is unde- fined,” as shown in Figure A-1.

Figure A-1. MSIE showing an error on line 23

However, if you look at the code in line 23 as shown in Figure A-2, nothing seems to be wrong.

Figure A-2. The code shown in UltraEdit with a highlight on line 23

The culprit is a typo in the function parameter, highlighted in Figure A-3, which means that outputID is not defined but outptID is. 6803.book Page 454 Thursday, June 15, 2006 2:24 PM

454 APPENDIX ■ DEBUGGING JAVASCRIPT

Figure A-3. The misspelled function parameter that caused the error

Typos in parameters are a very confusing bug, as browsers tell you the error occurred in the line where the variable is used and not where you made the mistake.

Incorrect Number of Closing Braces and Parentheses Another very common mistake is not closing curly braces or keeping an orphaned closing brace in the code when deleting some lines. Say, for example, you don’t need the isTree option any longer and you remove it from the code:

exampleCurly.html

function getFamilyData( outputID, familyName ) { var father, mother, child; switch( familyName ) { case 'Griffin': father = "Peter"; mother = "Lois"; child = "Chris"; break; case 'Flintstone': father = "Fred"; mother = "Wilma"; child = "Pebbles"; break; } var out = document.getElementById( outputID ); var newUL = document.createElement( 'ul' ); newUL.appendChild( makeListElement( father ) ); newUL.appendChild( makeListElement( mother ) ); newUL.appendChild( makeListElement( child ) ); 6803.book Page 455 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 455

out.appendChild( newUL ); } } getFamilyData( 'tree', true, 'Griffin' );

The orphan closing brace shown in bold will cause a “syntax error in line 30.” The same problem occurs when you don’t close all the braces in a construct, a mistake that can easily happen when you don’t indent your code:

exampleMissingCurly.html

function testRange( x, start, end ) { if( x <= end && x >= start ) { if( x == start ) { alert( x + ' is the start of the range'); } if( x == end ) { alert(x + ' is the end of the range'); } if( x! = start && x != end ) { alert(x + ' is in the range'); } else { alert(x + ' is not in the range'); } }

Running this example will cause an “expected ‘}’ in line 27” error, which is the last line of the script block. This means that somewhere inside the conditional construct we forgot to add a closing curly brace. Where the missing brace is supposed to be is rather hard to find, but a lot easier when the code is properly indented.

exampleMissingCurlyFixed.html

function testRange( x, start, end ) { if( x <= end && x >= start ) { if( x == start ) { alert(x + ' is the start of the range'); } if( x == end ) { alert(x + ' is the end of the range'); } if( x != start && x != end ) { alert(x + ' is in the range'); } } else { alert( x + ' is not in the range' ); } } 6803.book Page 456 Thursday, June 15, 2006 2:24 PM

456 APPENDIX ■ DEBUGGING JAVASCRIPT

The previously missing curly brace is shown in bold (following the “is in the range” alert() message). Not closing or closing too many parentheses is another common problem. This happens when you nest functions in if() conditions and later on delete some of them. For example:

if (all = parseInt(getTotal()){ doStuff(); }

This causes an error, as you forgot to close the parentheses of the condition itself.

if (all = parseInt(getTotal())){ ... }

It can also happen when you nest too many methods and returns:

var elm=grab(get(file).match(/(\w+)<\/id>/)[1];

This one lacks the closing parentheses after the [1]:

var elm=grab(get(file).match(/(\w+)<\/id>/)[1]);

In general, this kind of concatenation of functions is not good coding style, but there are situations where you will encounter examples like this one. The trick is to count the opening and the closing parentheses from left to right—good editors also highlight opening and closing parentheses automatically. You could also write a utility function to do this for you, which in itself is a test of your attention to detail when it comes to coding syntax:

exampleTestingCodeLine.html

function testCodeLine( c ) { if( c.match( /\(/g ).length != c.match( /\)/g) .length ) { alert( 'closing ) missing' ); } } c = "var elm=grab(get('demo.')" + ".match( /(\w+)<\/id>/ )[1] );"; testCodeLine( c );

Concatenation Gone Wrong Concatenation is happening a lot when you use JavaScript to output HTML. Make sure that you don’t forget the + signs in between the different parts to concatenate to a whole.

father = "Peter"; mother = "Lois"; child = "Chris"; family = father+" "+mother+" "child; 6803.book Page 457 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 457

The preceding lacks one addition sign before the child variable:

father = "Peter"; mother = "Lois"; child = "Chris"; family = father+" "+mother+" "+child;

Another obstacle is to make sure you don’t concatenate the wrong data types.

father = "Peter"; fAge = 40; mother = "Lois"; mAge = 38; child = "Chris"; cAge = 12; family = father + ", " + mother + " and " + child + " Total Age: " + fAge + mAge + cAge; alert( family );

This will not show the desired result, but this instead:

Peter, Lois and Chris Total Age: 403812

The mistake is that you concatenate strings and numbers as the + operator works from left to right. You need to add parentheses around the age term:

father = "Peter"; fAge = 40; mother = "Lois"; mAge = 38; child = "Chris"; cAge = 12; family = father + ", " + mother + " and " + child + " Total Age: " + (fAge + mAge + cAge); alert(family);

This results in the desired outcome:

Peter, Lois and Chris Total Age: 90 6803.book Page 458 Thursday, June 15, 2006 2:24 PM

458 APPENDIX ■ DEBUGGING JAVASCRIPT

Assigning Instead of Testing the Value of a Variable When testing the value of a variable, it is all too easy to assign it instead of testing it: all you need to do is forget an equal sign.

if(Stewie = "talking") { Brian.hear(); }

This will entice Brian to hear all the time, not only when Stewie has something to say; however, adding one equal sign does make Brian hear only when Stewie talks:

if(Stewie == "talking") { Brian.hear(); }

Tracing Errors with alert() and “Console” Elements The easiest way to trace errors is to use alert() wherever you want to test a certain value. The alert() method will stop the script execution (with the exception of calls that might still be going on in the background) and provide you with information about the value of a certain vari- able, and you can deduce if that value is correct or if it is the cause of the error. In some instances, using an alert() is not the right option, for example, if you want to trace the change of several values while looping through an array. Depending on the size of the array, this can become tedious, as you need to press Enter every time you want to get rid of the alert() and commence to the next array item. A workaround for this problem is coming up with your own debugging console or logging elements. Most JavaScript libraries come with a logging sublibrary (DOJO has dojo.logging, at http://manual.dojotoolkit.org/index.html#infrastructure; Mochikit has Log- ging, at http://mochikit.com/doc/html/MochiKit/Logging.html), and the DOMhelp library we put together in this book is no exception. You can use the initDebug(), setDebug(), and stopDebug() methods to simulate a debugging console. Simply add a style for the element with the ID DOMhelpdebug and use the methods to show the element and write content to it. For example:

exampleDebugTest.html (excerpt)

#DOMhelpdebug{ position:absolute; top:0; right:0; width:300px; height:200px; overflow:scroll; background:#000; color:#0F9; white-space:pre; font-family:courier,monospace; 6803.book Page 459 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 459

padding:1em; } html>body #DOMhelpdebug{ position:fixed; min-height:200px; height:200px; overflow:auto; }

exampleDebugTest.html (excerpt)

This example loops through the numbers 0 to 299 and displays whether the number can be divided by 3 without resulting in a floating point number. Instead of hitting Enter 300 times, all you need to do to see the results is to scroll in the “console window” you created with the earlier styles.

Error Handling with try and catch() You can test scripts using the try ... catch construct. Simply add the code you want to test inside a try condition and if there is an error, the code inside catch() will be executed. For example:

exampleTryCatch.js

try{ alert( 'this is a code example' ); alert( myVariable ); } catch( exceptionObject ) { // Predefine empty output var errorString = ''; for( i in exceptionObject ) { errorString += i + ':' + exceptionObject[i] + '\n'; } alert( errorString ); } 6803.book Page 460 Thursday, June 15, 2006 2:24 PM

460 APPENDIX ■ DEBUGGING JAVASCRIPT

The catch() method retrieves an Exception object as a parameter when an error occurs inside the try statement. You can give this object any variable name; in this example we call it exceptionObject. Depending on the error and the browser, this object will have different properties, and the properties that are the same across browsers will have different values. On MSIE 6 on Windows XP, the preceding code shows the bug—which is the second alert() trying to display an undefined variable—the following way:

name:TypeError message:'myVariable' is undefined number:-2146823279 description:'myVariable' is undefined

On 1.5.0.3 on Windows XP:

message:myVariable is not defined fileName:file:///c:/exampleTryCatch.html lineNumber:11 stack:@file:///c:/exampleTryCatch.html:11 name:ReferenceError

On 8.54 on Windows XP:

message:Statement on line 4: Reference to undefined variable: myVariable Backtrace: Line 4 of inline#1 script in file://localhost/C:/exampleTryCatch.html alert(myVariable); opera#sourceloc:4

If you try a different error, you will get the same properties, but different values. Let’s try to call a function that doesn’t exist by misspelling alert(). 6803.book Page 461 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 461

exampleTryCatchTypo.js

try{ allert( 'this is a code example' ); } catch( exceptionObject ) { var errorString = ''; for( i in exceptionObject ) { errorString += i + ':' + exceptionObject[i] + '\n'; } alert( errorString ); }

The results on MSIE 6 are the following:

name:TypeError message:Object expected number:-2146823281 description:Object expected

On Firefox 1.5.0.3:

message:allert is not defined fileName:file:///c:/exampleTryCatchTypo.html lineNumber:10 stack:@file:///c:/exampleTryCatchTypo.html:10 name:ReferenceError

On Opera 8.54:

message:Statement on line 3: Reference to undefined variable: allert Backtrace: Line 3 of inline#1 script in file://localhost/C://exampleTryCatchTypo.html allert("this is a code example"); opera#sourceloc:3 6803.book Page 462 Thursday, June 15, 2006 2:24 PM

462 APPENDIX ■ DEBUGGING JAVASCRIPT

Using try and catch in a debugging process can be very helpful, and depending on the browser, you can easily spot the problem.

■Note Notice that Opera reports the line number of the code inside the SCRIPT element, while Firefox reports the line number of the whole HTML document. MSIE leaves you in suspense where the error might have occurred when using try and catch().

However, as the construct in itself is JavaScript, you cannot debug JavaScript syntax errors with it:

exampleTryCatchFailing.js

try{ alert( 'this is a code example' ) ); } catch( exceptionObject ) { var errorString = ''; for( i in exceptionObject ) { errorString += i + ':' + exceptionObject[i] + '\n'; } alert( errorString ); }

The extra closing parenthesis after the first alert() is a syntax error that will cause the browser to show its built-in error messaging and stop the script from executing instead of exe- cuting the code inside the catch construct.

Sequential Uncommenting Another very easy way to trace an error is to comment out the whole script and uncomment it function by function or—if it is a single function—line by line. Test the script every time you uncomment a line by reloading it in a browser, and you will quickly get to the one that causes the error. This can take time though, and it would be much easier to know roughly where the error occurs, which is why you need to rely on your browser to give you this information. 6803.book Page 463 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 463

Error Reporting in Browsers Browsers help you to different degrees to debug your code. Following is a roundup of different browsers and their means of displaying errors and locating their origin. As I wanted to give an overview of different browsers you can use, I will not go into much further detail about the dif- ferent add-ons for each of them. Instead, I will provide you with some information and URLs where to get these add-ons and to read their documentation for yourself. The reason for this is not laziness on my behalf, but the fact that the number of browser add-ons and debugging tools for JavaScript increased a lot in the last year, with the advent of Ajax making JavaScript interesting again to a broader audience. Therefore, detailed explanations of a certain tool might be outdated once this book hits the shops.

Microsoft Internet Explorer 6 MSIE6 is probably still the most common browser on Windows these days. If you’re a developer, though, it doesn’t help you much—most of the time it throws errors other browsers don’t. Older versions of MSIE (4 and 5 on PC) showed a report window every time a JavaScript error occurred. This feature has been turned off in newer versions; you can turn it back on in the Browsing section of the Advanced tab under Tools ➤ Internet Options as shown in Figure A-4.

Figure A-4. Turning on error reporting in Microsoft Internet Explorer 6803.book Page 464 Thursday, June 15, 2006 2:24 PM

464 APPENDIX ■ DEBUGGING JAVASCRIPT

As the error messages provided by MSIE can be rather cryptic, like “Object does not sup- port this method or property,” and if MSIE is your only option for development, you might want to download the free Microsoft script at http://www.microsoft.com/downloads/ details.aspx?familyid=2F465BE0-94FD-4569-B3C4-DFFDF19CCD99&displaylang=en. The Microsoft Script Debugger is a debugging suite that allows you to set break points that stop the script execution until you tell it to go on. You can also use it to read the values of variables and change them while the script is running. All of this works outside the browser, which means you don’t need to resort to the tricks mentioned earlier like alert(), own debugging consoles, or sequentially comment out of parts of code. An introduction to the Microsoft Script Debug- ger is available at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ sdbug/Html/sdbug_1.asp.

Safari Apple’s flagship browser seemingly does not help you at all with JavaScript debugging. I said “seemingly” because there is a debugging menu in that is very handy; the only problem is that it is hidden by default. Enabling the debugging menu can be done in two ways: either via the command line or by installing the Safari enhancer. The command-line solution is pretty straightforward.

1. Close Safari.

2. Enter % defaults write com.apple.Safari IncludeDebugMenu 1 in the console (Applications ➤ Utilities ➤ Console) and hit Enter.

3. Restart Safari.

You’ll see that you have a new Debug menu option in the top menubar as shown in Figure A-5. Among many other useful features like a DOM tree viewer and the chance to simu- late other browsers for web sites that block out Safari, you have the options either to log JavaScript errors to the OS console or to show errors in a JavaScript console window. If you prefer a graphical user interface to change Safari, download the Safari enhancer shown in Figure A-6 at http://www.versiontracker.com/dyn/moreinfo/macosx/17776 and tick the box that states Activate Debugging Menu before pressing the Apply All Settings button. 6803.book Page 465 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 465

Figure A-5. The debugging menu of Safari

Figure A-6. Enabling the debugging menu with Safari Enhancer 6803.book Page 466 Thursday, June 15, 2006 2:24 PM

466 APPENDIX ■ DEBUGGING JAVASCRIPT

Opera 8.5 Opera not only comes with options to quickly turn off all kinds of browser support (JavaScript, cookies, plug-ins, pop-ups) by pressing F12, which helps immensely to test whether your web page is dependent on JavaScript or not, it also has a built-in JavaScript console that gives very detailed error reports. You can turn on the console via Tools ➤ Advanced ➤ JavaScript console as shown in Figure A-7.

Figure A-7. Showing the JavaScript console in Opera

Firefox 1.5.0.3 Firefox stays silent and doesn’t bother the visitor by reporting JavaScript errors. However, it comes with a very powerful JavaScript console, which you can show by selecting Tools ➤ JavaScript console on the main toolbar as shown in Figure A-8. 6803.book Page 467 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 467

■Note Don’t be confused if your Firefox browser doesn’t have the same options as shown in Figure A-8; some of them are dependent on extensions I installed. However, you should have the JavaScript console.

Figure A-8. Showing the JavaScript console in Firefox

Once activated, the JavaScript console is visible in its own browser window, which lists the JavaScript errors that occur in any page you open in any of your Firefox windows or tabs. It is quite amazing to see how many errors accumulate when you surf the Web a bit with the con- sole open. The error in exampleMissingCurly.html would display as shown in Figure A-9.

Figure A-9. The Firefox JavaScript console showing an error

You can either show errors, warnings, and messages, or filter the list for each of them. Clicking the Clear button will wipe the list clean. You can even evaluate any JavaScript by past- ing it into the code box and clicking the Evaluate button. 6803.book Page 468 Thursday, June 15, 2006 2:24 PM

468 APPENDIX ■ DEBUGGING JAVASCRIPT

By default, the JavaScript console will open in a new window, but there is a trick you can use to show it in the sidebar instead.

1. Make sure the bookmarks toolbar is visible by selecting View ➤ Toolbars ➤ Bookmarks Toolbar.

2. Right-click the toolbar and select New Bookmark.

3. Add the information shown in Figure A-10. The location must be chrome://global/ content/console.xul, but you can name the bookmark anything you like.

4. Make sure the Load this bookmark in the sidebar option is activated.

This will add a new bookmark button to the toolbar that opens the JavaScript console in the sidebar when you click it.

Figure A-10. A trick to make Firefox show the JavaScript console in the sidebar

This should get you started in spotting errors quickly in Firefox; however, it is only the tip of the iceberg when it comes to great helpers available for this browser. Mozilla and Firefox can be easily improved with extensions written in JavaScript and an XML-based language called XUL. 6803.book Page 469 Thursday, June 15, 2006 2:24 PM

APPENDIX ■ DEBUGGING JAVASCRIPT 469

Developers keep churning out new extensions and putting them on the Web. Two of those are very handy for you as a JavaScript developer:

The Web Developer Extension The Web Developer extension is a toolbar by Chris Pederick that is available at http:// www.chrispederick.com/work/webdeveloper/. This toolbar allows you to quickly toggle - Script support (which you can do otherwise via Tools ➤ Options ➤ Content ➤ Enable JavaScript), show HTML generated by JavaScript in the Source Viewer, populate forms auto- matically with data, edit the page’s style sheet on the fly, and choose from many more options. It is a “Swiss Army Knife” for web development.

FireBug If you thought the JavaScript console of Opera, Safari, and Firefox was handy, get the extension by Joe Hewitt (who is also responsible for the DOM inspector that is part of the default Firefox installation) at http://www.joehewitt.com/software/firebug/. The FireBug extension is visible in the bottom right of the browser window and either shows a warning icon with the number of errors in the console or a green icon indicating that everything is OK. If there are errors, you can click the icon (or press F12) to open the FireBug console in the bottom half of the browser window as shown in Figure A-11.

Figure A-11. The FireBug extension with open console

The features of FireBug are too many to mention here. Whatever is happening to the document, you can see it in the console. It shows the DOM structure, the applied CSS, the dimensions and properties of elements, events assigned to elements, the return values of Ajax requests, and much, much more. In the DOM inspector mode, you are even able to change the document on the fly to test changes quickly in a remote document. This is for testing purposes only—you cannot save the changes on the remote server, of course. 6803.book Page 470 Thursday, June 15, 2006 2:24 PM

470 APPENDIX ■ DEBUGGING JAVASCRIPT

Venkman Mozilla’s answer to the Microsoft Script Debugger is called Venkman and is available at https:// addons.mozilla.org/firefox/216/. Venkman is a full debugging suite that allows you to watch variables, set debugging points, and really go down into the depths of JavaScript development. Explaining all the features of Venkman would fill its own chapter, and for day-to-day JavaScript tasks, it may be overkill to use. If you want to know all the features of Venkman and how to use it, check the walkthrough provided on the homepage at http://www.mozilla.org/projects/ venkman/venkman-walkthrough.html. Another good start is the introductory article “Learning Venkman” by Svend Tofte, available at http://www.svendtofte.com/code/learning_venkman/. The newest versions of the aforementioned FireBug extension also include a debugger like Venkman, which makes it obsolete in some way; however, it is worth mentioning as it is in use in some companies.

JSLint and JSUNIT Some browser-independent tools are available that could also help you with JavaScript devel- opment. One is the online JavaScript verifier JSLint by , available at http:// www.jslint.com/lint.html. JSLint is a tool written in JavaScript that verifies scripts in terms of syntactical validity and tries to ensure good coding style. As “good coding style” is a subjec- tive matter, you may want to take JSLint reports with a grain of salt. JavaScript development happens mostly in browser environments, and from time to time you need to bend the rules or cut corners to make a script work faster or work around browser issues. That being said, it is still a great tool to find ways to optimize your scripts in terms of cleanliness of code if you don’t have to cut corners. The great thing about JSLint is that it gives you a full analysis of your script, including reports on global variables and how many times different functions have been called. If you come from a back-end coding environment, you may have already used or at least heard about (http://en.wikipedia.org/wiki/Unit_testing). In a very small nut- shell, unit testing means that you write test cases for all your methods and functions, and a “testing harness” allows you to run all these tests in succession when you press a button. This way you can ensure that your code works as you define the test cases it has to fulfill before you develop the code. For Java, there is JUnit; for PHP, there is PHPUnit; and yes, for JavaScript there is JSUnit, available at http://www.jsunit.net/.

Summary All in all, debugging JavaScript is much easier these days than it was some years ago, and espe- cially in the Firefox extension world it is very important to keep your eyes open, as new products that you may profit from are released almost weekly. The renaissance of JavaScript as part of the Ajax methodology has also made development IDE vendors a lot more aware of the need for good JavaScript debugging tools. Products that were traditionally meant exclusively for Java or .NET development are beginning to add support for JavaScript that goes beyond color-coding the sources. 6803index.fm Page 471 Friday, June 23, 2006 9:06 AM

Index

■Special Characters advantages of JavaScript, 5–6 #text nodes, 89 after( ) method, 425 $1 variable, 362 Ajax, back-end interaction with $(document).ready ( ) method, 421 and caching, 309 $.get( ) method, 425 connected select boxes, 323–331 % operator, 21 optional dynamic Ajax menus, 331–340 && operator, 48 overview, 299–309 * operator, 21 replacing XML with JSON, 314–316 */ syntax, JavaScript, 8 turning XML into HTML, 309–314 /* syntax, JavaScript, 8 using server-side scripts to reach // syntax, JavaScript, 8 third-party content, 316–320 \\ escape sequence, 20 XHR on slow connections, 320–322 || operator, 48 alert( ) method, 10, 90–95, 101, 121, 308, 452, 456, 458–459 + operator, 21, 23 Anim( ) method, 442–443 ++ operator, 21 animate( ) method, 443 != operator, 46 animation, 222–230 == operator, 46 APIs (application programming interfaces), 4 > operator, 46 appendChild( ) method, 312 >= operator, 46 application/x-www-form-urlencoded \' escape sequence, 20 content type, 329 / operator, 21 appName attribute, 65 ! operator, 49 appVersion attribute, 65 ■A Array data type, 30 abort( ) method, 321, 445 array_slice( ) method, 409 accessibility, 69–71 arrays accesskey attribute, 179 Array object addEvent( ) method, 166, 190, 325, 330, 433 converting array to string and back, addEventListener( ) method, 156, 166 43–44 addListener( ) method, 441 cutting slice of array, 42–43 addMap( ) function, 429 joining two arrays, 43 addOverlay( ) method, 432, 436 overview, 42 ADDRESS element, 125 sorting array, 44–45 overview, 39–42 471 6803index.fm Page 472 Friday, June 23, 2006 9:06 AM

472 ■INDEX

asynchronously, 300 overview, 463 attachEvent( ) method, 166 Safari, 464–465 attributes of elements vendors, 212 changing, 107–108 business logic layer, 63 reading, 117 button, 295 ■B button attribute, event object, 157 buttons, radio buttons, 281–284 \b escape sequence, 20 back( ) method, 230, 246 ■C background image, 192 caching, 309 background-position property, 191 camel notation, 24 before( ) method, 422 camelCase, 72 behavior layer, JavaScript as Campbell, Chris, 364 object detection vs. browser dependence, cancelClick( ) method, 169, 211, 219, 228, 65–68 325, 329–330, 372, 393, 395, 404, overview, 63–65 413–414 , 68–69 captions, displaying in thumbnail galleries, 396–401 block property, 261 Cascading Style Sheets (CSS), 61, 64 blocking software, 238 easing maintenance, 139–143 blur( ) method, 215, 219–220, 238, 276, 278 overview, 131 BODY element, 448 styling dynamic pages, 131–139 Boolean data type, 18, 45 support problems border property, 185 :hover pseudo-class, 148–152
line breaks, 426 multiple columns with same height, braces, closing, 454–456 143–148 (<>), 86 overview, 143 branches, breaking out of, 52 thumbnail galleries, 388 break statement, 52, 58 case statements, 52 browser cache settings, 212 case-sensitivity issues, 451 browser window, navigation methods of catch( ) method, 459–462 layer ads, 231–238 CDATA commenting syntax, 7 overview, 230–231 ceil( ) function, Math object, 37 browsers CGI (Common Gateway Interface), 3 browser dependence vs. object detection, chainable methods, 420 65–68 character encoding method, 20 error reporting in charAt(n) method, 346 Firefox, 466–470 charCodeAt( ) method, 346, 349 Microsoft Internet Explorer, 6 (MSIE6), 463–464 check boxes, 279–281 Opera, 466 checked attribute, 273, 279 6803index.fm Page 473 Friday, June 23, 2006 9:06 AM

■INDEX 473

checked property, 275, 279–281, 283–284, 294 CSS. See Cascading Style Sheets childNodes property, 100 CSS class, 248, 257, 398 children, 99–100 cssjs method, 149 Clark, Chris, 139 curly braces {} syntax, 8 click( ) method, 276 custom attribute, 366–367 click event, 163, 247, 249, 257, 259, 294 custom elements, 297 click event handler, 335 cutting slice of array, 42–43 client-side validation, pros and cons of, ■ 343–344 data comparison, 45–48 close( ) method, 215, 220 data conversion, 26–30 closestSibling( ) method, 120, 125, 178, 203, 294 data types, 17 closing braces, incorrect number of, 454–456 Date object, 30, 355–356 Find it faster at http://superindex.apress.com Find it faster CMS (Content Management System), 139 overview, 34 at http://superindex.apress.com Find it faster CODE element, 420, 426 using, 35–37 code execution, 9–11 DDA (Digital Discrimination Act), 6, 62 code layout, 72–74 Debug menu option, 464 code library, 426 debugging coding syntax, 24 common mistakes cols attribute, 276 assigning instead of testing value of variable, 458 columns, multiple with same height, 143–148 concatenation gone wrong, 456–457 commenting, 74–76 incorrect number of closing braces and complete property, 185 parentheses, 454–456 composite data types, 30 misspellings and case-sensitivity concat( ) method, Array object, 43 issues, 451 concatenation, 27, 456–457 overview, 451 concatenation operator, 23 trying to access undefined variables, conditional statements, 17 452–454 breaking out of branch or loop, 52 error handling with try and catch( ), overview, 49–52 459–462 confirm( ) method, 90–95, 215 error reporting in browsers console elements, tracing errors with, Firefox, 466–470 458–459 Microsoft Internet Explorer, 6 (MSIE6), constraintoviewport property, 447 463–464 Content-length, 329 Opera, 466 continue keyword, 58 overview, 463 converting array to string and back, 43–44 Safari, 464–465 converting different types of data, 26–30 JSLint and JSUNIT, 470 Cross-Site Scripting (XSS), 213 overview, 451 6803index.fm Page 474 Friday, June 23, 2006 9:06 AM

474 ■INDEX

debugging (continued) , 340 sequential uncommenting, 462 DOM (Document ), 67, 85 tracing errors with alert( ) and console accessing document via, 96–99 elements, 458–459 creating new nodes, 117 decision making methods, 277 comparing data, 46–48 navigating between nodes, 117 conditional statements overview, 116 breaking out of branch or loop, 52 reaching elements in document, 116 overview, 49–52 reading element attributes, node values, logical operators, 48 and other node data, 117 loops scripting, 63, 289 continuing, 58–59 DOM-2 event handling, 183 for loop, 54–56 DOMhelp library, 123, 190, 198, 419 overview, 54 do.while loop, 56, 59 while loop, 56–58 drag-and-drop interface, 179 overview, 45 dyn class, 232 switch statement, 52–54 dynamic Ajax menus, 331–340 testing multiple values, 52–54 dynamic class, 127, 267 delimiters, 18 dynamic pages, styling, 131–139 Developer Network, 438 dynamic slide shows, 207–211 DHTML, 5 dynamic technology syntax, 3 Diaz, Dustin, 139 ■E Digital Discrimination Act (DDA), 6, 62 each( ) method, 425 dimensions of windows, 221 Easing utility, 442 disabled attribute, 136, 285, 295 Edward, Dean, 345 disabled property, 138 Eisenberg, David, 367 disadvantages of JavaScript, 5–6 element node, 100 display property, 125, 130 element.innerHTML node, 117 DOCTYPE element, 85–86 elements, 39, 297 document object, 12, 15, 96, 184, 413 attributes of, changing, 107–108 . See DOM creating, removing, and replacing Document Type Definition (DTD), 86 avoiding NOSCRIPT, 113–115 document.createElement( ) method, 109, 117 DOM features, 116–117 document.createTextNode( ) method, overview, 109–113 109, 117 shortening scripts via innerHTML, documentElement.scrollTop property, 413 115–116 document.getElementById('id') element, 116 buttons, 284–286 document.getElementsByTagName check boxes, 279–281 ('tagname') element, 116 overview, 275–276 document.write( ) method, 15, 41, 89, 96, 174 6803index.fm Page 475 Friday, June 23, 2006 9:06 AM

■INDEX 475

radio buttons, 281–284 exec( ) method, 357 select boxes, 286–291 explanatory comments, 75 text fields, text areas, hidden and ■F password fields, 278–279 \f escape sequence, 20 using blur( ) and focus( ), 278 failed( ) method, 307–308, 313, 320, 330, 336 reading element attributes, node values, other node data, 117 false keyword, 281 elements collection, 276–277, 288 feedback else condition, 281 data validation else statement, 9, 15 highlighting erroneous fields individually, 376–379 tag, 153 instant validation feedback, 379–380 embedded slide shows, 197–207 overview, 369 enctype attribute, 274

replacing main form with clickable error at http://superindex.apress.com Find it faster error handling, with try and catch( ), 459–462 message, 374–376 error reporting, in browsers showing list of erroneous fields, 369–374 Firefox, 466–470 user feedback methods, 215 Microsoft Internet Explorer, 463–464 in web pages, 89–95 Opera, 466 filtering keyboard entries, 174–179 overview, 463 FireBug, 469 Safari, 464–465 Firefox, error reporting in escape sequence, 19 FireBug, 469 escape sequences, 19–20 overview, 466–469 eval( ) method, 188, 315–316 Venkman, 470 event bubbling, 158 Web Developer extension, 469 event capturing, 156 firstChild property, 100 event handling flash of unstyled content (FOUC), 173 changing document's behavior via Flash Satay, 153 events in W3C-compliant world, Flickr, 417 156–165 Flickr badges, 406 fixing events for non-W3C-compliant world, 165–172 floor( ) function, Math object, 37 overview, 153–156 focus( ) method, 215, 219, 238, 276, 278 reading and filtering keyboard entries, focus event, 243 174–179 focus pseudo-selector, 152 ugly page load problem, 173–174 for attribute, 365 dangers of, 179–180 for keyword, 54 event listener, 156 for loop, 54–56, 59, 98 event object, 157 for.in loop, 55 event target, 156 FORM element, 274, 305 Exception object, 460 Form object, 274 6803index.fm Page 476 Friday, June 23, 2006 9:06 AM

476 ■INDEX

form property, 275, 277 functionality, reusable code block form validation techniques wrappers, 11 CSS classes method, 366 sorting and reuse of, 80 custom attribute method, 366–367 variables and function scope, 80–81 designating mandatory fields, 364 ■G failures of these methods, 367 GBrowserIsCompatible( ) function, 429 hidden field method, 364–365 GET method, 305, 324 indicator element method, 365–366 GET parameter, 319 overview, 364 getAttribute( ) method, 108, 126, 249, 367 sharing validation rules, 367–369 getEl( ) method, 443 formmail.pl script, 364 getElementById( ) method, 96, 98–99, 103, forms, 297 184, 249, 251, 274, 448, 451 collection, 275–277 getElementById object, 68 custom elements, 297 getElementsByClassName( ) method, 96 elements getElementsByTagName( ) method, 96–99, buttons, 284–286 184, 274, 384, 448, 451 check boxes, 279–281 getTimezoneOffset( ) method, 37 globally supported properties, 277 GEvent.addListener( ) method, 432 HTML attributes not contained in GLatLng( ) method, 430 elements collection, 276 global reset, 209 overview, 275–276 global variable, 80 radio buttons, 281–284 GMap2( ) method, 430, 435 select boxes, 286–291 GMapTypeControl( ) method, 431 text fields, text areas, hidden and GMarker( ) method, 432, 436 password fields, 278–279 go(n) method, 246 using blur( ) and focus( ), 278 Good, Nathan A., 363 interactive, 291–297 Google AdSense, 416 methods, 274–275 Google Maps, 427–432, 434–437 overview, 272–274 Google Suggest, 381 properties, 274 GOverviewMapControl( ) method, 431 forms object, 274 GScaleControl( ) method, 431 forward( ) method, 230, 246 GSmallMapControl( ) method, 430 FOUC (flash of unstyled content), 173 GUnload( ) function, 429 Friedl, Jeffrey, 363 ■H function keyword, 77, 83 handleFailure( ) method, 447, 449 functions, 11, 76–80 handleSuccess( ) method, 447–448 calling, 11 hasChildNodes( ) method, 100, 120 creating own, 11 hash property, 245 6803index.fm Page 477 Friday, June 23, 2006 9:06 AM

■INDEX 477

HEAD element, 85 HTML element, 85, 428 tag, 85 .html file extension, 9 height attribute, 186 ■I height property, 185 id attribute, 89, 101, 246, 282 hidden fields, 278–279, 364–365 if( ) method, 456 hide( ) method, 422, 425 if condition, 67, 79, 172 HIJAX, 323 If keyword, 451 history object, 246 if statement, 9, 14, 49, 56 home( ) method, 230 IFRAME elements, 237 host property, 245 images hostname property, 245 image scripting basics, 184–186 hover method, 165 overview, 183 :hover pseudo-class, 148–152 preloading, 186 at http://superindex.apress.com Find it faster href attribute, 110, 137, 235, 246, 249–250, rollover effects 252–253, 257, 262, 269–270, 320, 330, 335, 338, 393, 399, 404, 410, 413–414, dynamic slide shows, 207–211 425, 447 embedded slide shows, 197–207 href property, 245 overview, 187 hspace property, 185 on parent elements, 192–196 HTML, 87 slide shows, 196 accessing document via DOM, 96–99 using several images, 187–191 anatomy of HTML document, 85–89 using single image, 191–192 changing attributes of elements, 107–108 images object, 67 children, 99–102 IMG element, 409, 414 creating, removing, and replacing index numbers, 40, 274 elements index property, 194 avoiding NOSCRIPT, 113–115 indexKey, 56 DOM features, 116–117 indexOf( ) method, 32, 346, 348, 350 DOMhelp, 118–122 innerHeight property, 213 overview, 109–113 innerHTML, 261 shortening scripts via innerHTML, innerHTML method, 308, 313–314 115–116 innerHTML property, 115–116, 394, 414, 422 overview, 85 innerWidth property, 213 parents, 99–103 in-page navigation, 246–255 providing feedback in web pages, 89–95 input element, 54, 295–297 siblings, 99–100, 103–107 , 285 turning XML into, 309–314 insertBefore( ) method, 267–268 html( ) method, 422 instant validation feedback, 379–380 HTML 4.01 STRICT, 87 interactive forms, 291–297 6803index.fm Page 478 Friday, June 23, 2006 9:06 AM

478 ■INDEX

IrfanView, 388 keypress handler, 175 isCallInProgress( ) method, 445 Koch, Peter-Paul, 160, 366 isNaN( ) method, 49, 352 ■L isNumber( ) method, 352 label element, 108 item( ) method, 100 lang attribute, 85 ■J Langridge, Stuart, 62 JavaScript object property syntax, 126 lastIndexOf( ) method, 32, 346, 348, 350 JavaScript overview, 1–4 layer ads, 231–238 definition, 4 Learning Venkman article, 470 functions, 11 Lemon, Gez, 247 objects, 12–13 length property, 31, 98, 203, 246, 274, 286, 290 problems and merits of, 5–6 line break (\n), 101 reasons for using despite reliability line-wrap option, 74 problems, 6–7 links, 110 running JavaScript, 9 literal values, 23 simple example, 13–15 LiveScript, 4 in web page and essential syntax load event, 156 code execution, 9–11 load method, 404, 412–413 functions, 11 local variables, 23 JavaScript syntax, 8–9 location property, 245 overview, 7 logical operators, 45, 48 what it is, 4 loops, 17 JavaScript Triggers article, 366 breaking out of, 52 join( ) method, 43, 288 continuing, 58–59 joining two arrays, 43 for loop, 54–56 jQuery, 419–427 overview, 54 .js file, 64, 80 while loop, 56–58 JSLint, 470 lowsrc property, 185 JSON, replacing XML with, 314–316 Ludwin, Daniel, 139 JSUNIT, 470 ■M ■K Macromedia Dreamweaver, 188 Keith, Jeremy, 323 mandatory field, 364–365 Keyboard access, 243 map_overview, 432 keyboard entries, reading and filtering, mapContainer, 435 174–179 maps, adding to sites with Google Maps, keyboard event handling, 179 427–432, 434–437 keyCode/data/charCode attribute, event mashups, 437 object, 157 Mastering Regular Expressions book, 363 keydown handler, 175 6803index.fm Page 479 Friday, June 23, 2006 9:06 AM

■INDEX 479

match( ) method, 129, 347, 357 pagination, 263–271 Math object, 30, 357 site navigation, 255–263 generating random number, 38 navigator data, 416 overview, 37 navigator object, 65 rounding numbers, 37–38 nested loops, 173 META element, 85 Netscape Navigator (NN) browser, 4 methods new keyword, 32 of forms, 274–275 nextSibling node, 118, 120 of String object, 32–34 Nicholls, Stu, 152 of window object node parameter, 120 animation with window intervals and node tree, 173 timeouts, 222–230 nodeName object, 100, 102, 277, 336, changing position and dimensions of 393, 395 Find it faster at http://superindex.apress.com Find it faster window, 221 node.nextSibling node, 117 navigation methods of browser window, node.nodeName attribute, 117 230–238 node.nodeType attribute, 117 opening new windows, 215–221 node.nodeValue attribute, 117 overview, 215 node.parentNode node, 117 user feedback methods, 215 node.previousSibling node, 117 microformat, 309 nodes, 117 Microsoft Internet Explorer (MSIE), 5, 64, node.setAttribute('attribute', 'value') 463–464 attribute, 117 Microsoft Script Debugger, 464 nodeType node, 118 misspellings, 451 nodeType object, 100 moofx, 341 nodeValue object, 100 mouseout event, 163 Nolan, Daniel, 188 mouseover event, 159, 163, 243 NOSCRIPT element, 113–115 mouseover handler, 252–253

480 ■INDEX

object detection, vs. browser dependence, Opera, 66, 217, 466 65–68 operators, 21–23 object literal, 82 optgroup, 295 tag, 153 Option constructor, 289 object-oriented programming (OOP), 3 options arrays, 323, 374 objects options object, 286 Date object options property, 276 overview, 34 outerHeight property, 213 using, 35–37 outerWidth property, 213 Math object ■P generating random number, 38 P element, 86 overview, 37 tags, 3 rounding numbers, 37–38 pageXOffset property, 213 String object pageYOffset property, 213 creating, 31–32 pageYOffset window object, 413 methods of, 32–34 pagination, 263–271 overview, 30 Panel( ) method, 448 obj.removeChild(oldNode) method, 109 panTo( ) method, 435, 437 offsetHeight attribute, 147 parameters, 11, 77 offsetHeight property, 235, 441 parentheses, 22 onAvailable( ) method, 444 grouping, 361–362 onchange event handlers, 70 incorrect number of, 454–456 onclick handler, 447 parentNode, 102, 131, 165, 267–268, 336 onCloseFn property, 434 parents, 100–103 onComplete event, 443 parseFloat( ) method, 28, 352 onComplete.subscribe( ) method, 443 parseInt( ) function, 28, 37, 352 one-size-fits-all validation myth, 345–346 password fields, 278–279 onevent properties, 157 password parameters, 305 onevent syntax, 169 pathname property, 245 onload event, 97, 173 period character (.), 358 onload event handler, window object, 69 file extension, 338 onmouseout event handler, 149 PHP script, 405, 408 onmouseover event handler, 149 phpThumb( ) class, 388 onreadystatechange event, 306, 321 Picasa, 388, 396 openInfoWindow( ) method, 433 Podcast Networks, 417 openInfoWindowHtml( ) method, 434, 436–437 pop-up windows, 444–449 opening new windows, 215–221 port property, 245 POST method, 305, 324, 328 6803index.fm Page 481 Friday, June 23, 2006 9:06 AM

■INDEX 481

PRE element, 420, 422, 425 parenthesis grouping, 361–362 preloading images, 186 resources, 363 presentation layer, changing, 123–131. See restricting number of characters with also Cascading Style Sheets quantifiers, 359–360 preventDefault( ) method, 161, 164, 168, 404 syntax and attributes, 357–358 previousSibling node, 120 whitespace, 360–361 previousSibling property, 103 wildcard searches, 358–359 primitive data types, 18 word boundaries, 360–361 print( ) method, 230 rel attribute, 137 problems with JavaScript, 5–6 reload( )method, 245 progressive enhancement, 68–69 removeAttribute( ) method, 128 prompt( ) method, 24–25, 33, 90–95, 215 removeChild( ) method, 236, 410 properties of forms, 274 render( ) method, 448 Find it faster at http://superindex.apress.com Find it faster properties string, 215 replace( ) method, 129, 204, 245–246, 249, 361 protocol property, 245 reset( ) method, 274, 278–279 prototype, 340 reset buttons, 284 proxy servers, 212 responseText method, 308, 313, 330 push buttons, 284 responseXML method, 308–309, 319 ■Q REST APIs, 417–419 return keyword, 77 quantifiers, 359 reuse of functions, 80 quotation marks, 18 reverse( ) method, 45 ■R Rico, 341 \r escape sequence, 20 rollover effects radio buttons, 281–284 dynamic slide shows, 207–211 random( ) method, Math object, 38 embedded slide shows, 197–207 random number, generating, 38 overview, 187 readability/functionality, 25 on parent elements, 192–196 reading keyboard entries, 174–179 slide shows, 196 ready( ) method, 424 using several images, 187–191 readyState property, 306–307, 321 using single image, 191–192 readystatechange event, 306 round( ) function, Math object, 37 RegEx Advice, 363 rounding numbers, 37–38 RegExp constructor, 361 rows attribute, 276 Regular Expression Library, 363 RSS feeds, 417–418 regular expressions ■ constraining scope, 358–359 S S@rdalya, 341 methods using, 361 Safari browser, 168, 404, 464–465 overview, 357 Sarissa, 341 6803index.fm Page 482 Friday, June 23, 2006 9:06 AM

482 ■INDEX

Scott, Leland, 340 slide shows screen object, 13, 15 dynamic, 207–211 screen readers, 69 embedded, 197–207 script block, 9 slideDown( ) method, 422 SCRIPT element, 113, 429, 438, 462 slideUp( ) method, 422

Web Analytics