Not much appears to happen, but reload the page by clicking the refresh icon or pressing F5,and the debugger will open at the next JavaScript statement executed.. If you have code in the
Trang 2Figure 10-12
You’ve already got debug_timestable.htmloaded, so select View ➪ Script Debugger ➪ Break at NextStatement Not much appears to happen, but reload the page by clicking the refresh icon or pressing F5,and the debugger will open at the next JavaScript statement executed
Where the next JavaScript statement occurs in your page depends on your code If you have code in thepage other than a function or code connected to an event handler, the first line the browser executes will
be the next JavaScript statement In your case, this is the code calling the following function:
<script>writeTimesTable(2)</script>
If there is no code in the page except code inside event handlers or functions, the next statement cuted will be that fired in an event handler, such as the windowobject’s onloadevent handler or a but-ton’s onclickevent handler
exe-Note that with some setups of the script debugger, the browser brings up a dialog box saying that anexception of type “Runtime Error” was not handled This does not mean that there is an error in thecode, but is simply the way Break at Next Statement works
As you can see from Figure 10-13, the next statement executed in your example occurs when the browserreaches the script embedded in your web page that calls the writeTimesTable()function Again, thisscript is highlighted in yellow by the debugger
373
Trang 3Figure 10-13
You’re now going to use the Step Into icon, illustrated here, which can be found on the top toolbar
Click this icon and the debugger will execute the current line of code and move to the next line, in thiscase your function (You’ll look more fully at stepping through code and examining the contents of vari-ables shortly.) You can also press the F8 key to step into the code, which is often easier than clicking theicon
Finally, let’s look at a third way of opening the debugger, which is probably the easiest and most useful.Imagine you want to stop your code’s execution and open the debugger just before the forloop is exe-cuted You can do this by simply adding the keyword debuggerto your script, which will stop the exe-cution at that point and open the debugger Let’s do that now
You need to close the debugger, return to your text editor, and add the following code to
writeString = counter + “ * “ + timesTable + “ = “;
Trang 4writeString = writeString + (timesTable * counter);
writeString = writeString + “<br>”;
document.write(writeString);
}}
Now refresh the page in Internet Explorer, and you’ll find that the debugger opens, with code executionpaused on the line with the debuggerkeyword in it (see Figure 10-14)
Figure 10-14
Again you can click the Step Into icon you used previously, and watch the code execute statement bystatement
Stepping Through Code
There are three important ways of stepping through code, each involving one of the icons from the toptoolbar of the script debugger
You’ve seen that one way is to step into the code This simply means that every line of code is executed
on a line-by-line basis If a function is called, you step into that function and start executing the codeinside the function statement by statement, before stepping out again at the end and returning to thecalling line To do this you use the Step Into icon
You may find that having stepped into a function you get halfway through and decide the function
is not the source of the bug, and that you want to execute the remaining lines of code in the function, then continue step by step from the point at which the function was called This is called stepping out of the function, and to do it you use the Step Out icon
375
Trang 5Instead of the icon you can press Ctrl+Shift+F8.
There may also be times when you have some code with a bug in it that calls a number of functions
If you know that some of the functions are bug-free, then you may want to just execute those tions instead of stepping into them and seeing them executed line by line For this the debugger has theStep Over icon, which executes the code within a function but without your having to go through it line byline
func-Or you can press Shift+F8
Let’s alter your times-table code in debug_timestable.htmand demonstrate the three kinds of ping action Note that the debuggerkeyword has been removed from the writeTimesTable()func-tion and is now in the second script block
writeString = counter + “ * “ + timesTable + “ = “;
writeString = writeString + (timesTable * counter);
writeString = writeString + “<BR>”;
document.write(writeString);
}}
Trang 7When you click the Step Into icon again, the timesTable = 1statement is executed and you step to thenext statement due to be executed, which is the condition part of the forloop With timesTableset to
1, you know that the condition timesTable <= 12is going to be true Click the Step Into icon and thecondition executes and indeed you find you’re right, the condition is true Now the first statementinside the forloop, document.write(“<P>”), is up for execution
When you click the Step Into icon again it will take you to the first calling of your writeTimesTable()function You want to see what’s happening inside that function, so click Step Into again and you’ll stepinto the function Your screen should look like the one shown in Figure 10-17
Figure 10-17
The next statement to be executed is not the var counter;or var writeString;line, but instead theforloop’s initialization condition The first two lines have been executed, but the script debugger doesnot enable us to step through variable declarations line by line
Click the Step Into icon a few times to get the gist of the flow of execution of the function In fact, ping through code line by line can get a little tedious So let’s imagine you’re happy with this functionand want to run the rest of it Start single-stepping from the next line after the function was called To dothis, click the Step Out icon
step-Now the function has been fully executed, and you’re back out of it and at the next line,
document.write(“</P>”), as you can see from Figure 10-18
Trang 8Figure 10-18
Click the Step Into icon to see that the document.write()line will be executed, and the next statement
in the flow of execution is the increment part of your forloop Click Step Into again and execution willcontinue to the condition part of the forloop Clicking Step Into twice more brings you back to the call-ing of the writeTimesTable()function You’ve already seen this in action, so really you want to stepover it and go to the next line Well, no prizes for guessing that the Step Over icon is what you need toclick to do this
Click the Step Over icon and the function will be executed, but without your having to step through itstatement by statement You should find yourself back at the document.write(“</P>”)line
If you’ve finished debugging, you can run the rest of the code without stepping through each line
by clicking the Run icon on the toolbar, shown after this paragraph Let’s do that; then you canreturn to the browser and see the results of the code you have executed You should see a page of timestables from 1*1=1to 11*12=132in the browser
Instead of clicking the icon you can also press the F5 key
379
Trang 9in the normal fashion (that is, without single-stepping) Then, when the breakpoint is reached, code cution will stop and you can start single-stepping if you want.
exe-To set the breakpoint, you need to scroll up the code window in the debugger until you can see theline on which you want to put the breakpoint Click that line; then click the Toggle Breakpoint icon
on the toolbar, shown here
Any line with a breakpoint on it is indicated by the reddish-brown dot on the left of the code windowand by the line itself being set to a reddish brown, although the line may not always be colored You canset as many or as few breakpoints at one time as you wish, so if you want to break on other lines you canadd breakpoints there too
To unset a breakpoint you just click the relevant line of code and click the Toggle Breakpoint iconagain, and that toggles it off To clear all breakpoints at once you can click the Clear All Breakpointsicon shown here (see Figure 10-19)
Okay, now let’s start the code running again by clicking the Run icon in the toolbar
You’ll find that the code resumes executing without single-stepping until it reaches your breakpoint, atwhich point it stops You can either single-step using the Step Into icon or click the Run icon again, inwhich case execution continues unless another breakpoint is reached
Leave the debugger open with code execution halted on your breakpoint; you’ll be using it in a moment
Trang 10Figure 10-19
The Command Window
While you’re stepping through code and checking its flow of execution, what would be really useful isthe ability to check the values contained inside variables, to evaluate conditions, and even to changethings on the fly You can do all of these things using the debugger’s command window
Hopefully you still have the debugger open with execution halted at the breakpoint you set previously.The line stopped on in Figure 10-19 is repeated here:
document.write(writeString);
Let’s see how you can find out the value currently contained in the variable writeString.First you need to open the command window from within the debugger You do this by clicking theCommand Window icon, illustrated here, or by selecting Command Window from the View menu
In the command window, type the name of the variable you want to examine, in this case writeString;then click Enter This will cause the value contained in the variable to be printed below your command
in the command window, as shown in Figure 10-20
381
Trang 11Figure 10-20
If you want to change a variable, you can write a line of JavaScript into the command window and pressEnter Try it with the following code:
writeString = “Changed on the Fly<BR>”
Now remove the breakpoint (see the previous section for instructions) and click the Run icon If youswitch to the browser, you see the results of your actions: Where the 1*1times table result should be, thetext you changed on the fly has been inserted Note that this alteration does not change your actualHTML source file, just the page currently loaded in the browser
The command window can also evaluate conditions Refresh the browser to reset the debugger andleave execution stopped at your debuggerstatement Click the Step Into icon twice and execution willstop on the condition in the forstatement
Type the following into the command window and press Enter:
timesTable <= 12
Because this is the first time the loop has been run, as shown in Figure 10-21, timesTableis equal to 1and so the condition timesTable <= 12evaluates to true Note that the debugger sometimes repre-sents trueby the value -1and falseby the value 0, so you may see the value -1instead of true
Trang 12Figure 10-21
You can also use the command window to access properties of the browser’s Browser Object Model(BOM) For example, if you type window.location.hrefinto the command window and press Enter,
it will tell you where the current page is stored
In fact, the command window can execute any single line of JavaScript including functions
Call Stack Window
When you are single-stepping through the code, the call stack window keeps a running list of whichfunctions have been called to get to the current point of execution in the code
Let’s create an example web page that demonstrates the call stack very nicely
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
secondCall();
}function secondCall(){
thirdCall();
}function thirdCall(){
383
Trang 13Save this page as debug_callstack.htm, and then load it into IE After you’ve done this, all you’ll see
is a blank web page with a button Click the button and the debugger will be opened at the debuggerstatement in the button1_onclick()function, which is connected to the button’s onclickevent handler
To open the call stack window, click the Call Stack icon in the toolbar, shown here, or choose CallStack from the View menu
Your debugger now looks like what is shown in Figure 10-22
Figure 10-22
Trang 14Every time a function is called, the debugger adds the function to the top of the call stack You canalready see that the first function called was actually the code attached to the onclickevent handler ofyour button The anonymous function is the event handler code that calls your onclickfunction Next,added to the call stack is the function called by the onclickevent handler, which is the function button1_onclick()shown at the top of the call stack.
If you want to see where each function was first entered, you need only double-click the function name
in the call stack window Double-click <Jscript> - Jscript - anonymous functionand the callingline — that is, the code connected to the onclickattribute of the <input>tag — will be shown Nowdouble-click the top line —<Jscript> - button1_onclick— and that will take you back to the currentexecution point
Now single-step twice, using the Step Into icon The first step is to the line that calls the firstCall()function The second step takes you into that function itself The function is immediately added to thecall stack, as shown in Figure 10-23
Figure 10-23
Click the Step Into icon again and you’ll step into the second function, secondCall() Again this isadded to the call stack One more click takes you into the third function, thirdCall(), again with itsname being added to the top of the call stack
Now click Step Into again and as you leave the function thirdCall()you will see that its name isremoved from the top of the call stack Another click takes you out of the second function
secondCall(), whose name is also now removed from the stack Each additional click takes you out of
a function, and removes its name from the call stack, until eventually all the code has been executed andyou’re back to the browser again
385
Trang 15Your demo page was very simple to follow, but with complex pages, especially multi-frame pages, thecall stack can prove very useful for tracking where you are, where you have been, and how you gotthere.
Running Documents Window
The final window you’ll look at is the running documents window This window lists each instance ofInternet Explorer running and shows you which pages, or documents, are currently loaded in thatinstance
Let’s create some example pages demonstrating the use of the running documents window
The running documents window proves most useful with frame-based pages, so let’s create a page withtwo frames inside it
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Frameset//EN”
“http://www.w3.org/TR/html4/frameset.dtd”>
<html>
<frameset rows=”50%,*”>
<frame name=”topFrame” src=”debug_topFrame.htm”>
<frame name=”bottomFrame” src=”debug_bottomFrame.htm”>
</frameset>
</html>
This first page defines the frameset Save it as debug_frameset.htm
Next is the page for the top window
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
Trang 16Finally, enter the third page.
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
This will initially show each instance of Internet Explorer running on the machine Click the plus sign toopen a window that shows which pages are currently loaded, or running, in that instance of InternetExplorer When pages are in framesets, as ours are, then pages contained within the window framesetpage are included, indented underneath the frameset page (see Figure 10-24) You’ll need to click theplus sign again to open them
The easiest way to debug the code within the top frame is to right-click debug_topFrame.htmin theRunning Documents window and select Break at Next Statement Then click the button in the top frameand the debugger will open, with execution stopped at the first statement due to be executed
(onclick=”return button1_onclick()”)
387
Trang 17Figure 10-24
That concludes your brief tour of the Microsoft script debugger This debugger is excellent for ging pages so that they will work in IE However, it won’t help us spot errors caused by cross-browserincompatibility For example, what works in Firefox might throw an error in IE, and a page that you’vedebugged successfully in IE could easily throw an error in Firefox Aside from this problem, the debug-ger is a great help for spotting logic errors in your code
debug-F irefox Debugging with Venkman
Like IE, Firefox has a debugger of its own, called Venkman It provides all the features and debuggingpower of the IE debugger: For example, you can step into, over, and out of your code, work with break-points, and access a call stack window
You can download Venkman from
https://addons.mozilla.org/firefox/216/
Unfortunately, at the time of this writing, September 2006, Venkman and Firefox have bugs that make their use together difficult After the initial install Venkman works, but later attempts to open it fail Firefox must be restarted for Venkman to work again Hopefully by the time you read this Venkman will
be working again!
To install Venkman, open Firefox and go to the mozilla.orgURL mentioned earlier; then follow theinstructions After Venkman is installed you’ll need to close down and restart Firefox A brief guide toVenkman can be found at:
Trang 18When Firefox is reopened you can launch the debugger If you now look under the Tools ➪ JavaScriptDebugger menu you will see that an extra menu option has appeared (see Figure 10-25).
Figure 10-25
Choosing JavaScript Debugger opens Venkman, as shown in Figure 10-26
Figure 10-26
389
Trang 19The important first step is to launch Venkman Then you can load the page or frameset that you wish todebug into Firefox Leave Venkman open, switch to Firefox, and load the debug_timestable2.htmfileyou created earlier As soon as it’s loaded the page runs and comes to a stop on the debugger commandand highlights where it has stopped, just as in the IE debugger (see Figure 10-27).
Figure 10-27
Although the layout and icons are different from those in the IE debugger, the concepts are the same, asare the sorts of things you can do As Figure 10-27 shows, the black background of the interactive win-dow at the bottom-right corner is basically the same as in the IE debugger’s command window In thelong text box below it you can enter JavaScript code, just as with the IE debugger If you enter
timesTableinto the text box and press Enter, it will tell you the value contained in the timesTablevariable, which, because it hasn’t yet been given, is currently void
Click the Step Into icon on the debugger’s toolbar and the code goes to the next line The step over, stepinto, and step out commands work here very much as they do in the IE debugger, but there are some dif-ferences For example, the forloop head is just one step with Venkman, whereas the MS debugger steps
to the initialization first and then to the condition Also, while the MS debugger runs over variable larations, Venkman doesn’t
dec-Keep stepping until you are in the writeTimesTable()function, as shown in Figure 10-28
Trang 20Figure 10-28
Notice that the window in the middle on the left-hand side, named Local Variables, has changed It nowshows under the heading scopethe variables within the scope of this function In this function these arethe counter, timesTable, and writeStringvariables The current values of each variable are alsoshown, void in the case of variables yet to be assigned a value
In the bottom left-hand corner are the Breakpoints and Call Stack windows Currently you see only theBreakpoints window, but by clicking the Call Stack tab under the window you can switch to that win-dow (You can switch back with the Breakpoints tab.) Click the Call Stack tab to show the current state ofthe call stack, as shown in Figure 10-29
As Figure 10-29 shows, there are two items in the call stack: the writeTimesTable()function call andthe code that called it
To set a breakpoint, you click the gray area in the source code window on the line where you want to set
a breakpoint (see Figure 10-30)
391
Trang 21Figure 10-29
Figure 10-30
Trang 22In Figure 10-30, we clicked the gray area on the writeString = counter line, and the gray area hasturned red and been marked with the letter Bto show it’s a breakpoint If you click the breakpoint again
it will turn orange and be marked with the letter Fto indicate that this is a future breakpoint Clicking athird time removes the breakpoint Alternatively, you could right-click the breakpoint listed in the break-point window and clear it there — or, indeed, clear all breakpoints Note that a future breakpoint is abreakpoint that is not set for this execution of the code but that will be set next time the page is executed,for example if you reload the page
The final window is the Loaded Scripts window, situated in Figure 10-30 in the top left-hand corner Thisshows currently loaded files In your case there is just one document, but there can be more than one if,for example, a frameset is loaded This is the equivalent of the IE debugger’s Running Documents win-dow
The Venkman debugger is a little more sophisticated than the basic IE debugger, and it’s worth readingthe full and quite extensive documentation on the Venkman home page for details
❑ Murphy’s Law states that anything that can go wrong will go wrong!
browser/platform is not supported
2. Validate your data If there is a way for users to enter dud data that will cause your program tofall over, then they will If your code will fall over if a text box is empty, you must check that ithas something in it If you need a whole number, you must check that that’s what the user hasentered Is the date the user just entered valid? Is the e-mail address mind your own businessthe user just entered likely to be valid? No, so you must check that it is in the format
something@something.something
393
Trang 23Okay, so let’s say you’ve carefully checked your pages and there is not a syntax or logic error in sight.You’ve added data validation that confirms that everything the user enters is in a valid format Thingscan still go wrong, and problems may arise that you can do nothing about Here’s a real-world example
of something that can still go wrong
Yours truly, Paul, created an online message board that used something called remote scripting, aMicrosoft technology that enables us to transfer data from a server to a web page It relies on a smallJava applet to enable the transfer of data Paul checked the code and everything was fine After launch-ing the board, it worked just fine, except that in about 5 percent of cases the Java applet initialized, butthen caused an error To cut a long story short, remote scripting worked fine, except in a small number ofcases where the user was behind a particular type of firewall (a firewall is a means of stopping hackersfrom getting into a local computer network) Now, there is no way of determining whether a user isbehind a certain type of firewall, so there is nothing that can be done in that sort of exceptional circum-stance Or is there?
In fact IE 5+ and Firefox include something called the try catchstatement It’s also part of theECMAScript 3 standard This enables you to try to run your code; if it fails, the error is caught by thecatchclause and can be dealt with as you wish For the message board, Paul used a try catchclause to catch the Java applet’s failure and redirected the user to a more basic page that still displayedmessages, but without using the applet
Let’s now look at the try catchstatements
The try catch Statements
The try catchstatements work as a pair; you can’t have one without the other
You use the trystatement to define a block of code that you want to try to execute
You use the catchstatement to define a block of code that will execute if an exception to the normalrunning of the code occurs in the block of code defined by the trystatement The term exception is key here: It means a circumstance that is extraordinary and unpredictable Compare that with an error, which
is something in the code that has been written incorrectly If no exception occurs, the code inside thecatchstatement is never executed The catchstatement also enables you to get the contents of theexception message that would have been shown to the user had you not caught it first
Let’s create a simple example of a try catchclause
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
alert(‘This is code inside the try clause’);
alert(‘No Errors so catch code will not execute’);
}
catch(exception)
{
Trang 24if (exception.description == null){
alert(“Firefox says the error is “ + exception.message)}
else{alert(“Internet Explorer says the error is “ + exception.description);
}}
Next comes the catchstatement You’ve included exceptionin parentheses right after the catchment This exceptionis simply a variable name It will store an Exceptionobject containing informa-tion about any exception thrown during execution of code inside the trycode block Although you’veused exception, you could use any valid variable name For example, catch(exceptionObject)would be fine and certainly more descriptive
state-The Exceptionobject contains two properties that provide information about the exception thatoccurred The bad news is that while both IE and Firefox support the Exceptionobject and both havetwo properties, the names of these properties differ
The IE version of the Exceptionobject has the numberand descriptionproperties The numbererty is a unique number for that error type The descriptionproperty is the error message the userwould normally see
prop-With Firefox, the properties of the Exceptionobject are nameand message The nameproperty is aunique name for that type of error and the messageproperty is much like the IE descriptionproperty
in that it gives a more detailed explanation of what went wrong These properties are also part of theECMAScript 3 standard and IE and Opera 6+ support them
Within the curly braces after the catchstatement is the code block that will execute if and only if anerror occurs In this case, the code within the trycode block is fine, and so the alert()method insidethe catchblock won’t execute
Insert a deliberate error
try{alert(‘This is code inside the try clause’);
ablert (‘Exception will be thrown by this code’);
}catch(exception){
if (exception.description == null)
395
Trang 25{alert(“Firefox says the error is “ + exception.message)}
else{alert(“Internet Explorer says the error is “ + exception.description);
}}
Now when you load the page, the first alert()method, the tryblock of code, will execute fine and thealert box will be displayed to the user However, the second ablert()statement will cause an error andcode execution will start at the first statement in the catchblock
Because the IE and Firefox Exceptionobjects support different properties, you need different code foreach How do you tell whether the browser is IE or Firefox?
By checking to see whether the exception.descriptionproperty is null,you can tell whether thedescriptionproperty is supported, and therefore whether the browser is one of those supporting theproperty, such as IE If the property is equal to null, it is not supported by the browser, so you need todisplay the messageproperty of the Exceptionobject instead If the property is not null, it hasavalue and therefore does exist and can be used
If you’re using Internet Explorer, the error description displayed will be Object expected If you’reusing Firefox, the same error is interpreted differently and reported as ablert is not defined
If you change the code again, so it has a different error, you’ll see something important
try
{
alert(‘This is code inside the try clause’);
alert(‘This code won’t work’);
}
catch(exception)
{
if (exception.description == null){
alert(“Firefox says the error is “ + exception.message)}
else{alert(“Internet Explorer says the error is “ + exception.description);
}}
If you load this code into an IE or Firefox browser, instead of the error being handled by your catchclause, you get the normal browser error message telling you Expected ‘)’
The reason for this is that this code contains a syntax error: The functions and methods are valid, butyou have an invalid character The single quote in the word won’thas ended the string parameter beingpassed to the alert()method At that point JavaScript syntax, or language rules, specifies that a closingparenthesis should appear, which is not the case here Before executing any code, JavaScript goesthrough all the code and checks for syntax errors, or code that breaches JavaScript’s rules If a syntax
Trang 26error is found, the browser deals with it as usual; your tryclause never runs and therefore cannot dle syntax errors.
it more gracefully than with lots of JavaScript errors
To use throw,you type throwand include the error message after it
throw “This is my error message”;
Remember that when you catch the Exceptionobject in the catchstatement, you can get hold of theerror message that you have thrown Although there’s a string in this example throwstatement, you canactually throw any type of data, including numbers and objects
Try It Out try catch and Throwing Errors
In this example you’ll be creating a simple factorial calculator The important parts of this example arethe try catchclause and the throwstatements It’s a frameset page to enable us to demonstrate thatthings can go wrong that you can’t do anything about In this case, the page relies on a function definedwithin a frameset page, so if the page is loaded on its own, a problem will occur
First let’s create the page that will define the frameset and that also contains an important function
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
Trang 27Save this page as CalcFactorialTopFrame.htm.
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
if (window.top.calcFactorial == null)throw “This page is not loaded within the correct frameset”;
if (document.form1.txtNum1.value == “”)throw “!Please enter a value before you calculate its factorial”;
if (isNaN(document.form1.txtNum1.value))throw “!Please enter a valid number”;
if (document.form1.txtNum1.value < 0)throw “!Please enter a positive number”;
document.form1.txtResult.value =window.parent.calcFactorial(document.form1.txtNum1.value);
}catch(exception){
if (typeof(exception) == “string”){
if (exception.charAt(0) == “!”){
alert(exception.substr(1));
document.form1.txtNum1.focus();
document.form1.txtNum1.select();
}else{alert(exception);
}}else{
if (exception.description == null){
alert(“The following error occurred “ + exception.message)
}else{alert(“The following error occurred “ + exception.description);}
}}}
</script>
</head>
<body>
Trang 28<form name=”form1”>
<input type=”text” name=txtNum1 size=3> factorial is
<input type=”text” name=txtResult size=25><br>
<input type=”button” value=”Calculate Factorial”
Figure 10-31
The factorial of a number is the product of all the positive integers less than or equal to that number Forexample, the factorial of 4 (written 4!) is 1 * 2 * 3 * 4 = 24 Factorials are used in various branches of math-ematics, including statistics Here, you want only to create a function that does something complexenough to be worthy of a function, but not so complex as to distract you from the main purpose of thisexample: the try catchand throwstatements
If you clear the first text box and click Calculate Factorial, you’ll be told that a value needs to be entered
If you enter an invalid non-numeric value into the first text box, you’ll be told to enter a valid value Ifyou enter a negative value, you’ll be told to enter a positive value
Also, if you try loading the page CalcFactorial.htminto your browser and enter a value in the textbox and click Calculate Factorial, you’ll be told that the page is not loaded into the correct frameset
As you’ll see, all of these error messages are created using the try catchand throwstatements
399
Trang 29How It Works
Because this example is all about try catchand throw,you’ll concentrate just on the
CalcFactorial.htm page, in particular the butCalculate_onclick()function, which is connected
to the onclickevent handler of the form’s only button
You’ll start by looking at the tryclause and the code inside it The code consists of four ifstatementsand another line of code that puts the calculated factorial into the second text box Each of the ifstate-ments is checking for a condition that, if true, would cause problems for your code
The first ifstatement checks that the calcFactorial()function, in the top frameset window, actuallyexists If not, it throws an error, which will be caught by the catchblock If the user loads the
CalcFactorial.htmpage rather than the frameset page CalcFactorialTopFrame.htm,then withoutthis throwstatement your code will fail
try{
if (window.top.calcFactorial == null)throw “This page is not loaded within the correct frameset”;
The next three ifstatements check the validity of the data entered into the text box by the user First youcheck that something has actually been entered in the box, then that what has been entered is a number,and then finally you check that the value is not negative Again if any of the ifconditions is true, youthrow an error, which will be caught by the catchblock Each of the error messages you define startswith an exclamation mark, the purpose of which is to mark the error as a user input error, rather than anerror such as not being in a frameset
if (document.form1.txtNum1.value == “”)throw “!Please enter a value before you calculate its factorial”;
if (isNaN(document.form1.txtNum1.value))throw “!Please enter a valid number”;
if (document.form1.txtNum1.value < 0)throw “!Please enter a positive number”;
If everything is fine, the calcFactorial()function will be executed and the results text box will befilled with the factorial of the number entered by the user
document.form1.txtResult.value =window.parent.calcFactorial(document.form1.txtNum1.value);
}
Finally, turn your attention to the catchpart of the try catchstatement First, any message thrown
by the trycode will be caught by the exceptionvariable
catch(exception){
The type of data contained in exceptionwill depend on how the error was thrown If it was thrown bythe browser and not by your code, exceptionwill be an object, the Exceptionobject If it’s thrown byyour code, then in this instance you’ve thrown only primitive strings So the first thing you need to do isdecide what type of data exceptioncontains If it’s a string, you know it was thrown by your code and
Trang 30can deal with it accordingly If it’s an object, and given that you know none of your code throws objects,you assume it must be the browser that has generated this exception and that exceptionis an
Exceptionobject
if (typeof(exception) == “string”){
If it was code that generated the exception using a throw(and so exceptionis a string), you now need
to determine whether the error is a user input error, such as the text box not containing a value to late, or whether it was another type of error, such as the page not being loaded in your frameset All theuser input exception messages had an exclamation mark at the beginning, so you use an ifstatement tocheck the first character If it is a !, you notify the user of the error and then return focus to your control
calcu-If it’s not, you just display an error message
if (exception.charAt(0) == “!”){
alert(exception.substr(1));
document.form1.txtNum1.focus();
document.form1.txtNum1.select();
}else{alert(exception);
}}
If exceptionwas not a string, you know you have an exceptionobject and need to display either themessageproperty if it’s Firefox or the descriptionproperty if it’s IE You use if e.description ==nullcheck to see which property is supported
else{
if (exception.description == null){
alert(“The following error occurred “ + exception.message)}
else{alert(“The following error occurred “ + exception.description);
}}}
Nested try catch Statements
So far you’ve been using just one try catchstatement, but it’s possible to include a try catchstatement inside another trystatement Indeed, you can go further and have a try catchinside thetrystatement of this inner try catch, or even another inside that, the limit being what it’s actuallysensible to do
So why would you use nested try catchstatements? Well, you can deal with certain errors insidethe inner try catchstatement If, however, you’re dealing with a more serious error, the inner catchclause could pass that error to the outer catchclause by throwing the error to it
401
Trang 31Here’s an example.
try
{
try{ablurt (“This code has an error”);
}catch(exception){
var eMessage
if (exception.description == null){
eMessage = exception.name;
}else{eMessage = exception.description;
}}}
catch(exception)
{
alert(“Error the inner try catch could not handle occurred”);
}
In this code you have two try catchpairs, one nested inside the other
The inner trystatement contains a line of code that contains an error The catchstatement of the innertry catchchecks the value of the error message caused by this error If the exception message is eitherObject expectedor ReferenceError, the inner try catchdeals with it by way of an alert box
In fact, both the exception messages checked for are the same thing, but reported differently by IE andFirefox Note that these examples use the Firefox Exceptionobject’s nameproperty rather than themessagefor comparison, because nameis a much shorter one-word description of the exception thanmessage, which is a sentence describing the exception
However, if the error caught by the inner catchstatement is any other type of error, it is thrown up inthe air again for the catchstatement of the outer try catchto deal with
Let’s change the butCalculate_onclick()function from the previous example, CalcFactorial.htm,
so that it has both an inner and an outer try catch
Trang 32function butCalculate_onclick() {
try{try{
if (window.top.calcFactorial == null)throw (“This page is not loaded within the correct frameset”);
if (document.form1.txtNum1.value == “”)throw(“!Please enter a value before you calculate its factorial”);
if (isNaN(document.form1.txtNum1.value))throw(“!Please enter a valid number”);
if (document.form1.txtNum1.value < 0)throw(“!Please enter a positive number”);
document.form1.txtResult.value =window.parent.calcFactorial(document.form1.txtNum1.value);
}catch(exception){
if (typeof(exception) == “string” && exception.charAt(0) == “!”){
alert(exception.substr(1));
document.form1.txtNum1.focus();
document.form1.txtNum1.select();
}else{throw exception;
}}}catch(exception){
switch (exception){
case “This page is not loaded within the correct frameset”:
alert(exception);
break;
default :alert(“The following critical error has occurred \n” + exception);
}}}
The inner try catchdeals with user input errors However, if the error is not a user input errorthrown by us, it is thrown for the outer catchstatement to deal with The outer catchstatement has aswitchstatement that checks the value of the error message thrown If it’s the error message thrown by
us because the calcFactorialTopFrame.htmis not loaded, the switchstatement deals with it in thefirst casestatement Any other error is dealt with in the defaultstatement However, there may well
be occasions when there are lots of different errors you want to deal with in casestatements
403
Trang 33finally Clauses
The try catchstatement has a finallyclause that defines a block of script that will executewhether or not an exception was thrown The finallyclause can’t appear on its own; it must be after atryblock, which the following code demonstrates
❑ You first looked at some of the more common errors, those made not just by JavaScript ners, but also by experts with lots of experience
begin-❑ You installed the script debugger, which works with Internet Explorer Without the scriptdebugger any errors throw up messages, but nothing else With the script debugger you get tosee exactly where the error might have been and to examine the current state of variables whenthe error occurred Also, you can use the script debugger to analyze code as it’s being run,which enables you to see its flow step by step, and to check variables and conditions
❑ You looked at Venkman, the script debugger for Firefox You saw that it works much like the IEdebugger and in some ways is superior to it Although these debuggers have different inter-faces, their principles are the same
❑ Some errors are not necessarily bugs in your code, but in fact exceptions to the normal stances that cause your code to fail (For example, a Java applet might fail because a user isbehind a firewall.) You saw that the try catchstatements are good for dealing with this sort
circum-of error, and that you can use the catchclause with the throwstatement to deal with likelyerrors, such as those caused by user input Finally, you saw that if you want a block of code toexecute regardless of any error, you can use the finallyclause
In the next chapter you’ll be looking at a way to store information on the user’s computer using
some-thing called a cookie Although they may not be powerful enough to hold a user’s life history, they are
certainly powerful enough for you to keep track of a user’s visits to your web site and of what pages he
Trang 34var formValid = true;
var elementCount = 0;
while(elementCount =< theForm.length){
if (theForm.elements[elementcount].type == “text”){
if (theForm.elements[elementCount].value() = “”)alert(“Please complete all form elements”)theForm.elements[elementCount].focus;
formValid = false;
break;
}}return formValid;
}
</script>
<form name=form1 onsubmit=”return checkForm(document.form1)”>
<input type=”text” ID=text1 name=text1>
Trang 36For example, imagine a user, whose name you asked on the first visit, returns to your web site.You could welcome her back to the web site by greeting her by name Another good example isgiven by a web site, such as Amazon’s, that incorporates the one-click purchasing system Byalready knowing the user’s purchasing details, such as credit-card number and delivery address,you can allow the user to go from viewing a book to buying it in just one click, making the likeli-hood of the user purchasing it that much greater Also, based on information, such as the previouspurchases and browsing patterns of the user, it’s possible to make book suggestions.
Such personalization requires that information about users be stored somewhere in between theirvisits to the web site Previous chapters have mentioned that accessing the user’s local file systemfrom a web application is pretty much off limits because of security restrictions included inbrowsers However, you, as a web site developer, can store small amounts of information in a spe-
cial place on the user’s local disk, using what is called a cookie There may be a logical reason why
they are named cookies, but it also provides authors with the opportunity to make a lot of rate, food-related jokes!
second-Baking Your F irst Cookie
The key to cookies is the documentobject’s cookieproperty Using this property, you can createand retrieve cookie data from within your JavaScript code
You can set a cookie by setting document.cookieto a cookie string You’ll be looking in detail at
how this cookie string is made up later in the chapter, but let’s first create a simple example of acookie and see where the information is stored on the user’s computer
Trang 37<script language=”JavaScript” type=”text/javascript”>
document.cookie = “UserName=Paul;expires=Tue, 28 Dec 2020 00:00:00;”;
Before you view the cookies, you’ll first clear the temporary Internet file folder for the browser, becausethis will make it easier to view the cookies that your browser has stored In IE, select Internet Optionsfrom the Tools menu, which is shown in Figure 11-1
Trang 38Having selected this option, you’ll be presented with the Internet Options dialog box shown in Figure 11-2.
Figure 11-2
Click the Delete button under Browsing History Another dialog box appears, as shown in Figure 11-3
Figure 11-3
409
Trang 39Click the Delete files button next to Temporary Internet Files, and select Yes when it asks if you’re sure.You now have a nice clean cache, which makes it easy to see when you create a cookie You can nowclose the dialog box and return to the main Internet Options dialog box.
Let’s have a look at the cookies you have currently residing on your machine From the Internet Optionsdialog box, click the Settings button next to the Delete button grouped under Browsing History Youshould see the dialog box shown in Figure 11-4
Figure 11-4
Now click the View Files button, and a list of all the temporary pages and cookie files on your computerwill be displayed If you followed the previous instructions and deleted all temporary Internet files,there should be nothing listed except any cookies from web sites you’ve visited, as shown in Figure 11-5.The actual cookies, their names, and their values, may look slightly different depending on your com-puter’s operating system