34
murach s JavaScript and D OM Scripting (Chapter 3) Thanks for downloading this chapter from Mur ac h’ s J a v aScr ipt and DOM Scr ipting. We hope it will show you how easy it is to learn from any Murach book, with its paired-pages presentation, its “how-to” headings, its practical coding examples, and its clear, concise style. To view the full table of contents for this book, you can go to our w e bsite. From there, you can read more about this book, you can find out about any additional downloads that are available, and you can review our other books on web development. Thanks for your interest in our books! TRAINING & REFERENCE MIKE MURACH & ASSOCIATES, INC. 1-800-221-5528 • (559) 440-9071 • Fax: (559) 440-0963 [email protected] www .m ur ac h.com Copyright © 2009 Mike Murach & Associates. All rights reserved.

DocumentJS

Embed Size (px)

Citation preview

TRAINING & REFERENCE

murachs

JavaScriptand

DOM Scripting

(Chapter 3)Thanks for downloading this chapter from Murachs JavaScript and DOM Scripting. We hope it will show you how easy it is to learn from any Murach book, with its paired-pages presentation, its how-to headings, its practical coding examples, and its clear, concise style. To view the full table of contents for this book, you can go to our website. From there, you can read more about this book, you can find out about any additional downloads that are available, and you can review our other books on web development. Thanks for your interest in our books!

MIKE MURACH & ASSOCIATES, INC.1-800-221-5528 (559) 440-9071 Fax: (559) 440-0963 [email protected] www.murach.comCopyright 2009 Mike Murach & Associates. All rights reserved.

iii

ContentsIntroduction Section 1 Introduction to JavaScript programming Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Introduction to web development and JavaScript How to code a JavaScript application How to test and debug a JavaScript application A crash course in XHTML A crash course in CSS 3 43 89 121 169 xiv

Section 2 JavaScript essentials Chapter 6 Chapter 7 Chapter 8 Chapter 9 Chapter 10 Chapter 11 Chapter 12 How to get input and display output How to work with numbers, strings, and dates How to code control statements How to create and use arrays How to create and use functions How to create and use objects How to use regular expressions, handle exceptions, and validate data 223 249 275 301 327 355 385

Section 3 DOM scripting Chapter 13 Chapter 14 Chapter 15 Chapter 16 Chapter 17 Chapter 18 Basic DOM scripting Advanced event handling Advanced DOM manipulation How to script CSS How to script tables and forms Animation with DOM scripting 421 469 523 555 591 633

Section 4 Other JavaScript skills Chapter 19 Chapter 20 How to control the web browser How to use JavaScript libraries 663 701

Reference Aids Appendix A Index How to set up your computer for this book 745 753

Chapter 3

How to test and debug a JavaScript application

89

3How to test and debug a JavaScript applicationAs you build a JavaScript application, you need to test it to make sure that it performs as expected. Then, if there are any problems, you need to debug your application to correct any problems. This chapter shows you how to do both. Since JavaScript runs in a web browser, you can only use the testing and debugging tools that are provided by the browser. But, as you will see, these tools are limited when compared to the tools that are provided by an integrated development environment like Visual Studio or NetBeans.An introduction to testing and debugging ........................ 90Typical test phases for a JavaScript application ........................................... 90 The three types of errors that can occur ....................................................... 90 Common JavaScript errors ........................................................................... 92 How to get error messages with Firefox ...................................................... 94 A simple way to trace the execution of your JavaScript code ...................... 96

How to debug with the Firebug extension of Firefox ....... 98How to install and enable the Firebug extension ......................................... 98 How to get information in the Console tab ................................................ 100 How to review your code in the Script tab ................................................. 102 How to use breakpoints and step through code .......................................... 104

How to use the Firebug console object ........................... 106The methods of the console object ............................................................. 106 How to trace an application with Firebugs console.log method ............... 108

How to test and debug with other browsers ................... 110How to get error messages with Internet Explorer ..................................... 110 How to get error messages with Safari ....................................................... 112 How to get error messages with Opera ...................................................... 114 How to get error messages with Chrome ................................................... 116

Perspective ........................................................................ 118

90

Section 1

Introduction to JavaScript programming

An introduction to testing and debuggingWhen you test an application, you run it to make sure that it works correctly. As you test the application, you try every possible combination of input data and user actions to be certain that the application works in every case. In other words, the goal of testing is to make an application fail. When you debug an application, you fix the errors (bugs) that you discover during testing. Each time you fix a bug, you test again to make sure that the change that you made didnt affect any other aspect of the application.

Typical test phases for a JavaScript applicationWhen you test an application, you typically do so in phases, like the three that are summarized in figure 3-1. In the first phase, as you test the user interface, you should visually check the controls to make sure theyre displayed properly with the correct text. Then, you should make sure that all the keys and controls work correctly. For instance, you should test the Tab key and Enter key as well as the operation of check boxes and drop-down lists. In the second phase, you should test the application with valid data. To start, you can enter data that you would expect a user to enter. Before youre done, though, you should enter valid data that tests all of the limits of the application. In the third phase, you go all out to make the application fail by testing every combination of invalid data and user action that you can think of. That should include random actions like pressing the Enter key or clicking the mouse at the wrong time.

The three types of errors that can occurAs you test an application, there are three types of errors that can occur: These errors are described in figure 3-1. Because syntax errors prevent your application from running, they are the easiest to find and fix. As you will see, a typical web browser provides error messages that help you do that. Although runtime errors dont violate the syntax rules, they do throw exceptions that stop the execution of an application. Unlike other languages, though, JavaScript doesnt throw many of the traditional exceptions. For instance, if you divide a number by zero, JavaScript returns infinity instead of throwing an exception. As a result, most JavaScript exceptions involve problems with the use of identifiers. Logic errors can come from many places, and they are often the most difficult to find and correct. A mistake in a calculation, events not being triggered in the order you expect them to, and working with incorrect values are just a few of the ways that logic errors can creep into your applications. The Sales Tax application in this figure has a logic error. Can you tell what it is?

Chapter 3

How to test and debug a JavaScript application

91

The Sales Tax application with a logic error

The goal of testing To find all errors before the application is put into production.

The goal of debugging To fix all errors before the application is put into production.

Three test phases Check the user interface to make sure that it works correctly. Test the application with valid input data to make sure the results are correct. Test the application with invalid data or unexpected user actions. Try everything you can think of to make the application fail.

The three types of errors that can occur Syntax errors violate the rules for how JavaScript statements must be written. These errors are caught by the web browser. Runtime errors dont violate the syntax rules, but they throw exceptions that stop the execution of the application. Logic errors are statements that dont cause syntax or runtime errors, but produce the wrong results.

Description To test a JavaScript application, you run it to make sure that it works properly no matter what combinations of valid or invalid data you enter or what sequence of controls you use. When you debug an application, you find and fix all of the errors (bugs) that you find when you test the application.An introduction to testing and debugging

Figure 3-1

92

Section 1

Introduction to JavaScript programming

Common JavaScript errorsFigure 3-2 presents some of the coding errors that are commonly made as you write a JavaScript application. If you study this figure, youll have a better idea of what to watch out for. And if you did the exercises for the last chapter, youve probably experienced some of these errors already. The code at the top of this figure is the start of the code for the Future Value application but with four errors introduced into the code. The first one is in the second line. The error is that getElementByID should be getElementById. Remember that JavaScript is case-sensitive. Can you spot the other three errors? If not, youll get a chance to find them when you do the exercises for this chapter. Two problems that are peculiar to JavaScript are also discussed in this figure. The first involves floating-point arithmetic. JavaScript uses the IEEE 754 standard for floating-point numbers. Unfortunately, this standard can introduce strange results with even simple calculations. The figure suggests one way of dealing with this issue. The other problem involves the way JavaScript converts values when performing comparisons. The general rule is that when JavaScript compares two values that are of different types, it converts them both to number values. It does this even if one is a string and the other is a Boolean value. So the expression 1 == true will return true because true is converted to 1, and the expression 0 == false will also return true because false will be converted to 0. Testing for equality with the value NaN can also be troublesome because the expression NaN == NaN will return false. But youll learn more about that in chapter 7.

Chapter 3

How to test and debug a JavaScript application

93

JavaScript code that contains errorsvar $ = function (id) { return document.getElementByID(id); } var calculate_click = function () { var investment = parseFloat( $("investment").value ); var annualRate = parseFloat( $("rat").value ); var years = parseInt( $("years").value ; $("futureValue").value = ""; }

Common syntax errors Misspelling keywords. Forgetting an opening or closing parenthesis, bracket, brace, or comment character. Breaking a single line into two valid statements where JavaScript inserts a semicolon. Forgetting to use a semicolon that is essential to the logic of the code. Forgetting an opening or closing quote mark. Not using the same opening and closing quote mark.

Problems with identifiersMisspelling or incorrectly capitalizing an identifier. Using a reserved word, global property, or global method as an identifier.

Problems with valuesNot checking that a value is the right data type before processing it. For example, you expect the user to enter a date, but he enters a name instead. Forgetting to use the parseInt or parseFloat function to convert a user entry into a numeric value. Using one equal sign instead of two when testing for equality.

A problem with floating-point arithmeticThe number data type in JavaScript uses floating-point numbers and that can lead to arithmetic math errors. For example, 0.2 + 0.7 in JavaScript is 0.8999999999999999. One way around this is to round the number to the desired decimal place with the toFixed method and then convert it back to a floating-point number with the parseFloat method.

A problem with comparing values of different data types When you compare two values that are of different data types, JavaScript will internally convert both values to numbers. In this conversion, an empty string is converted to 0; true is converted to 1; and false is converted to 0. This can lead to unexpected result when using the equality operator. For example, the expression 0 == will evaluate to true since an empty string is converted to 0.Common JavaScript errors

Figure 3-2

94

Section 1

Introduction to JavaScript programming

How to get error messages with FirefoxWhen you run the Future Value application with the errors shown in figure 3-2, the interface will still be displayed. When you try to use the application, however, it wont do anything because of the errors. To see the error messages that Firefox produces, open the Error Console as as in figure 3-3. Here, as you learned in chapter 2, the console shows the first error thats detected when the Future Value application is run with the errors of the previous figure. In this case, the arrow under the message points to the character in the line that caused the error. The mistake is that a leading double quotation mark is matched by a single quotation mark, which is invalid. To display the source code for a JavaScript file, you can click on the link in the error message. That opens the source code in a separate window with the error highlighted. You cant use that window to fix the code, though. Instead, you need to use your editor to fix and save the code and then restart the application in Firefox by clicking on the Reload button. Often, the error messages are not as clear as in this example. Instead, an error in one line will be reported as an error somewhere else. Then, you start by looking for the error in the line indicated in the error message, but work your way to related portions of code until you find the error. The tabs at the top of the Error Console let you select which types of messages you want displayed. If you use many extensions or themes or if you have several pages open in tabs, all of their messages, warnings, and errors will be displayed in the same Error Console window. Then, you can show just the errors by clicking the Errors tab. You can also remove all messages from the Error Console by clicking the Clear button. You can also use the Error Console to evaluate JavaScript expressions. To do that, you type the code you want to evaluate in the Code text box and click the Evaluate button. Then, the results will be displayed in the Error Console. Note, however, that you cant use functions or variables in an expression in the Error console. In this figure, the second message in the Error Console, which displays 101, is the result of the expression in the Code text box. Incidentally, the error message in this figure is for the first error thats detected when the code in the previous figure is run, but that error isnt the first one in the code. Thats because the JavaScript engine only detects syntax errors as the page is being loaded, but the first error in the code is a runtime error. The JavaScript engine wont run the application until all of the syntax errors have been corrected. Then, the $ function will be called and its runtime error will be detected.

Chapter 3

How to test and debug a JavaScript application

95

The Firefox Error Console with an error displayed

The source code thats displayed when you click on the link

How to display the Error Console and source code To display the Error Console, use the Tools Error Console command or press Ctrl+Shift+J. To display the source code with the error highlighted, click on the link in the Error Console.

How to evaluate expressions with the Error Console Enter the expression in the Code text box and click the Evaluate button. Note, however, that you cant use functions or variables in the expression.

Description The Error Console in Firefox is used to display errors, warnings, and messages generated by web pages. That includes messages caused by errors in JavaScript code. The buttons at the top of the Error Console let you display all errors, just fatal errors, just warnings, or just messages. The Clear button removes all errors from the console. If you click the link to the file in the Error Console, Firefox will display the code and highlight the line at which the error occurred. You will not, however, be able to edit the file.

Figure 3-3

How to get error messages with Firefox

96

Section 1

Introduction to JavaScript programming

A simple way to trace the execution of your JavaScript codeWhen you trace the execution of an application, you add statements to your code that display messages or variable values at key points in the code. This is typically done to help you find the cause of a logic error. If, for example, you cant figure out why the future value thats calculated by the Future Value application is incorrect, you can insert three alert statements into the code for the application as shown in figure 3-4. These functions display dialog boxes that show the values for four of the variables as the code is executed. That should help you determine where the calculation is going wrong. Then, when you find and fix the problem, you can remove the alert statements. When you use this technique, you usually start by adding just a few alert statements to the code. Then, if that doesnt help you solve the problem, you can add more. This works well for simple applications, but has its limitations. Later in this chapter, youll learn other debugging techniques as well as a more sophisticated method of tracing the execution of an application.

Chapter 3

How to test and debug a JavaScript application

97

JavaScript with alert statements that trace the execution of the codevar calculate_click = function () { var investment = parseFloat( $("investment").value ); var annualRate = parseFloat( $("rate").value ); var years = parseInt( $("years").value ); $("futureValue").value = ""; var monthlyRate = annualRate / 12 / 100; alert("Monthly Rate = " + monthlyRate); var months = years * 12; alert("Months = " + months); var futureValue = 0; for ( i = 1; i >>. To run code in this command line, type the code and press the Enter key. To expand the command line, click the red up arrow at the right side of the command line. The expanded command line is the pane on the right of the panel. To run code in this pane, enter the code and click Run to execute the code. To clear the code, click Clear. To collapse this pane, click the red down arrow at the bottom right of the command pane.

How to get a profile of the functions that were called To get a profile of the functions that were called, click the Profile button at the top of the Firebug panel to start the profiler. Then, after youve run the application a few times, click the Profile button again to display the profile report in the Console tab. Note: In the profile above, an error in Firebug causes the $ function to be displayed as (?). This indicates an unknown function name and should be corrected in later releases of this extension.

Description One of the uses of the Firebug Console tab is to display error messages like those that are displayed by the Error Console. If you click on the code link, the Script tab is opened and the line that caused the error is highlighted. A stack trace shows the functions that were called prior to the error with the most recent call at the top of the trace. To display a stack trace when an error message is displayed in the Console tab, click on the error message link or the plus sign before the link.

Figure 3-6

How to get information in the Console tab

102

Section 1

Introduction to JavaScript programming

How to review your code in the Script tabThe Script tab displays the JavaScript code for an application. This is illustrated by the Script tab in figure 3-7. This figure also shows you how to use this tab to review the JavaScript code for the current web page. When you use this tab, you can review three types of scripts. A static script is a script in a file. An eval script is code that is dynamically executed by a call to the global eval method. And an event script is a script that is present in an event attribute of an XHTML tag such as the onclick attribute of the input tag. In this book, though, event scripts arent used, and eval methods arent presented because they expose your scripts to security vulnerabilities. If you want the code in the Script tab highlighted with colors, you need to install the Rainbow extension for the Firebug extension. To do that, you must have Firebug version 1.2 or higher and Firefox version 3.0 or higher. If you add this extension to an earlier version of Firebug or Firefox, Firebug will no longer work so please take this as a warning. In that case, you will have to uninstall the Rainbow extension to get Firebug to work again.

Chapter 3

How to test and debug a JavaScript application

103

The Script tab in Firebug

How to switch between JavaScript files If you have more than one JavaScript file for a web page, use the drop-down list that says futureValue.js in the screen above to switch from one file to another.

How to search through the code or jump to a line number Type your code in the search box in the upper right of the Firebug panel. Then, press Enter to find the next occurrence of your search term. Or, to jump to a line number in the code, type a pound sign (#) followed by a line number in the search box.

How to display the types of scripts that you want to see Use the drop-down list that shows all in the screen above. This lets you select combinations of static, eval, and event scripts. Because you probably wont be using eval or event scripts, though, you can leave this setting at all.

Description In the Script tab, the code is displayed in black and white. If you want to enhance this so color is used to highlight specific coding elements, you can install the Rainbow extension for Firebug, as shown in appendix A. Although you can use the features of the Script tab to find errors, you cant change the code. You still need to use your text editor to make the changes.

Figure 3-7

How to review your JavaScript code in the Script tab

104

Section 1

Introduction to JavaScript programming

How to use breakpoints and step through codeA breakpoint is a point in your code at which the execution of your application will be stopped. Then, you can examine the contents of variables and the execution stack to see if your code is executing as expected. You can also step through the execution of the code from that point on. These techniques can help you solve difficult debugging problems. Figure 3-8 shows you how to set breakpoints, step through the code in a JavaScript application, and view the contents of variables in the Watch pane. In the illustration, you can see that a breakpoint has been set on line 16 of the Future Value application. When you run your application, it will stop at the first breakpoint that it encounters and display a yellow triangle on top of that breakpoint. While your code is stopped, you can hover your mouse over an objects name in the Script tab to display the current value of that object. At a breakpoint, you can also view the current variables in the Watch pane on the right side of the panel. Those are the variables that are used by the function that is being executed. You can also see the value of other variables and expressions by clicking New watch expression and typing the variable or expression you want to watch. (Note that the i variable in the for loop isnt listed in the Watch pane in this figure because it isnt created until the for statement is executed.) To step through the execution of an application after a breakpoint is reached, you can use the Step Into, Step Over, and Step Out buttons. If you repeatedly click the Step Into button, you will execute the code one line at a time and the next line to be executed will be highlighted. After each line of code is executed, you can use the Watch tab to observe any changes in the variables. You can also click the Stack tab to view a stack trace that shows all of the executing functions and the value of their parameters. As you step through an application, you can click the Step Over button if you want to execute any called functions without executing them. Or, you can use the Step Out button to step out of any functions that you dont want to step through. When you want to return to normal execution, you can click the Continue button. Then, the application will run until the next breakpoint is reached. These are powerful debugging features that can help you find the causes of serious debugging problems. Stepping through an application is also a good way to understand how the code in an existing application works. If, for example, you step through the loop in the Future Value application, youll get a better idea of how that loop works.

Chapter 3

How to test and debug a JavaScript application

105

A breakpoint in the Firebug Script tabContinue, Step Into, Step Over, and Step Out buttons

How to set a breakpoint If necessary, use the drop-down list above the Script tab to select the right JavaScript file. Then, to set a breakpoint, click in the bar to the left of a statement. The breakpoint is marked by a red dot. To set a conditional breakpoint, right-click on a statement and enter a conditional expression in the resulting dialog box. Then, the application only stops at the breakpoint if the condition is true.

How to step through JavaScript code from a breakpoint Click the Step Into button to step through the code one line at a time. At each step, the Watch tab displays the values of the current variables. You can also hover the mouse cursor over a variable name to display its current value. Click the Step Over button to execute any called functions without stepping through them. Click the Step Out button to execute the rest of a function without stepping through it. Or, click the Continue button to resume normal execution.

How to set a watch expression Click New watch expression in the Watch tab and type the variable name or the expression that you want to watch.

How to disable or remove breakpoints To remove a breakpoint, click on the red breakpoint marker in the Script tab, or click on the close button for the breakpoint in the Breakpoints tab. To disable a breakpoint, click on the check box for it in the Breakpoints tab.

Description You can set a breakpoint on any line except a blank line. When the JavaScript engine encounters a breakpoint, it stops before it executes the statement that contains the breakpoint. To see a stack trace when youre stepping through an application, click on the Stack tab.How to set breakpoints and step through the execution of your code

Figure 3-8

106

Section 1

Introduction to JavaScript programming

How to use the Firebug console objectFor most applications, youll be able to test and debug your applications with the features that have been presented thus far. In some cases, though, you may need to use some of the methods of the Firebug console object to get information. In particular, you can use the console.log method to do an extensive trace of the execution of an application. If youre new to programming, you can skip this topic and come back to it later because it uses some coding techniques that wont be presented until later in this book. If youre an experienced programmer, though, this is worth a quick read.

The methods of the console objectWhen the Firebug Console tab is enabled, it adds an object to the JavaScript environment called the console object. This object provides many methods for reporting information in the Console tab. The more common methods are summarized in figure 3-9. For instance, the log method can be used to display messages in the Console tab, the profile method turns on the profiler, and the profileEnd method turns off the profiler. If the console object isnt available, though, the use of a console method causes a runtime error. This can happen if the Firebug extension isnt installed or the Firebug Console tab isnt enabled. To prevent errors when the console object isnt available, you can wrap the console methods in if statements or functions that test for the existence of the console object before using one of its methods. This is illustrated by the code in this figure, which tests for the presence of the console object and its log method before using the console.log method. You can also use a debug flag to control console logging even if the console object is available. A debug flag is just a global Boolean variable that indicates whether or not debugging should take place. For instance, the code that follows defines a debug flag and sets it to true:var debug = true; // Set to false to skip debugging

This code should be near the start of the JavaScript code so its easy to find. Next, you modify any wrapper code so it checks the value of the debug flag before using any of the console methods. For instance, the code in this figure would be expanded to look like this:if ( debug && typeof console == "object" && console.log ) { console.log ("Function complete."); }

Now, if you set the debug flag to true and the console object is present, this code will call the console.log method. But if you set the debug variable to false, this code wont call the log method even if the console object is present.

Chapter 3

How to test and debug a JavaScript application

107

Common methods of the Firebug console objectMethodlog() debug() info() warn() error() assert()

DescriptionDisplays a message in the console. It takes one or more objects as parameters to display. Displays a message in the console and includes a link to the source of the message. It takes one or more objects as parameters to display. Displays a message with an information icon in the console and includes a link to the source of the message. It takes one or more objects as parameters to display. Displays a message with a warning icon in the console and includes a link to the source of the message. It takes one or more objects as parameters to display. Displays a message with an error icon in the console and includes a link to the source of the message. It takes one or more objects as parameters to display. Displays an error message in the console and throws an exception if the boolean expression in its first parameter is false. It takes a Boolean expression as its first parameter and optional objects to display in the console if the assertion fails. Displays an interactive list of the objects properties. It takes one object as a parameter. Turns on the Firebug profiler which times every function call. It takes one optional parameter which is a string to display in the console. Turns off the Firebug profiler and displays the report in the console.

dir() profile() profileEnd()

Examples of the console object methods// Log the value of the months variable in the console. console.log("Months", months); // Display an error message in the console. console.error("User entered an invalid value for months.");

How to test for the presence of the console object and the log methodif (typeof console == "object" && console.log) { console.log ("Function complete."); }

Description The methods of the console object give you many ways to track and report what your program is doing. If the console object isnt available, youll get a runtime error if you try to use it. To avoid that, you can use the code above, which tests to see whether the console object and the log method are available. Go to http://getfirebug.com/console.html for a complete list of the methods of the console object.

Figure 3-9

The methods of the Firebug console object

108

Section 1

Introduction to JavaScript programming

How to trace an application with Firebugs console.log methodOne of the uses of the console.log method is to trace the execution of an application. This is illustrated by figure 3-10. In this case, the log method is used to display variable names and values at various points in the code. This data will be displayed in the Console tab as the application executes. When the application is finished, you can review this data. This will help you determine where the bug is. Then, youll have more information that will help you determine what the logic error is and how to fix it. Note, however, that the log method isnt used directly in this figure. Instead, its wrapped in the $log function. That will prevent runtime errors from occurring when the console object isnt available. In chapter 10, youll learn how the apply method of a function works, but for now just know that the $log function accepts any number of parameters and uses the log function to display them in the Console tab. Statements that use the $log function are then inserted in strategic places in the code of the Future Value application to trace its execution.

Chapter 3

How to test and debug a JavaScript application

109

The JavaScript file for the Future Value application with execution tracingvar $log = function () { if (typeof console == "object" && console.log ) { console.log.apply(console, arguments); } } var $ = function (id) { return document.getElementById(id); } var calculate_click = function () { var investment = parseFloat( $("investment").value ); var annualRate = parseFloat( $("rate").value ); var years = parseInt( $("years").value ); $log("investment", investment); $log("annualRate", annualRate); $log("years", years); $("futureValue").value = ""; var monthlyRate = annualRate / 12 / 100; var months = years * 12; var futureValue = 0; $log("monthlyRate", monthlyRate); $log("months", months); for ( i = 1; i