Appendix A Troubleshooting

This appendix identifies problems commonly encountered when working with script, images, and HTML, and it offers suggestions for avoiding them. For additional troubleshooting information on these and other topics related to working on the Web, check the resources and tools listed in Appendix B.

A Boolean Expression Doesn't Evaluate As Expected

A common mistake in JScript, especially in an if statement, is to use the assignment operator (=, a single equal sign) in a Boolean expression instead of the equality operator (==, two equal signs). For example, assuming that variable a has a value of 4, you might mistakenly write this expression to set up an alert:

 if (a=5){alert("!")} 

This line does not test for equality between a and 5, however. Instead, it assigns the value 5 to a. The expression will not evaluate to false, and thus the alert is always generated.

The correct expression is the following:

 if (a==5){alert("!")} 

This expression tests for equality and generates the alert only if a is equal to 5. Since a equals 4, the alert is not generated.

To review the logical operators commonly used in Boolean expressions or to find more information about writing if statements, refer to Chapter 9.

A Style Doesn't Change When Set

When you work with CSS, you can address an attribute in two ways. In in-line HTML and in style sheets, the specific attribute name should be lowercase, with a hyphen between the words that comprise the name. A colon separates the attribute name from the value being assigned to it, as shown here for font-style:

 <SPAN ID="span1" STYLE="font-style: italic"> 

In script, you access a CSS attribute through its corresponding property in the Dynamic HTML Object Model, as explained in Chapter 15. The name of the property and the name of the attribute can differ. Hyphens are not used in property names, and any letter that followed a hyphen in the corresponding attribute name is capitalized in the property name. (Thus, the font-style attribute corresponds to the fontStyle property.) In script code, you must use an equal sign to separate the property name from the value being assigned to it, and you must enclose in quotation marks any values that are not numbers or variable names, as shown here:

 span1.style.fontStyle="italic" 

If you use the wrong naming convention or the wrong separator, you will find that the style is not correctly set. For example, if we had omitted the quotation marks around the italic setting in the preceding line, we would have received the error message `italic' is undefined. A different error would have resulted from using a colon as the separator instead of the equal sign.

The Browser Says an Object Is Not an Object

Your browser might occasionally generate an error message telling you that an element of your code is not an object. This error usually results from having either multiple objects with the same name or no object with the specified name. Code Listing A-1 offers an example.

Code Listing A-1.

 <HTML> <HEAD> <TITLE>Listing A-1</TITLE> </HEAD> <BODY> <SPAN ID="span1">This is a span.</SPAN> <SPAN ID="span1">This is another span.</SPAN> <SCRIPT LANGUAGE="JavaScript"> span1.style.fontStyle="italic" </SCRIPT> </BODY> </HTML> 

When you run Code Listing A-1 in Microsoft Internet Explorer, the error message `span1.style' is not an object appears because the code contains more than one object with the name span1. As a result, Internet Explorer cannot determine which object it should change. When Code Listing A-1 is displayed in Netscape Navigator, the Communicator Console (if visible) will display the error span1 is not defined. You can access the Communicator Console by typing javascript: into the Go to field (similar to the Address field in Internet Explorer). When accessing a nonexistent object in Netscape Navigator, sometimes no error message will result and the script appears to do nothing. If you are having problems using objects across browsers, you might look into helpful third-party tools, such as Scott Isaac's DHTMLLib, available at www.insidedhtml.com.

The Browser Expects a Parenthesis or a Curly Brace

When you receive a message reflecting this type of error, you'll often notice that the browser is referring to a line of code that does not contain script. It does so because a parenthesis or a curly brace should have been included in a previous line. As an example, look at Code Listing A-2.

Code Listing A-2.

 <HTML> <HEAD> <TITLE>Listing A-2</TITLE> <SCRIPT LANGUAGE="JavaScript"> <!-- function test() alert("This is an alert!" //--> </SCRIPT> </HEAD> </HTML> 

Code Listing A-2 contains three mistakes. When the code is executed, Internet Explorer displays an error message reading Line: 7 Char: 1 Error: Expected `{` Code: 0 while the Communicator Console for Netscape Navigator 4 displays the error line 7: missing { before function body. Because line 6 of this code defines a function, it should include the opening curly brace that is required after the set of parentheses. The next code the browser encounters is the alert on line 7; at this point, it already should have encountered the curly brace, and so it displays the error message.

If you run this code again after fixing the first mistake (by placing a curly brace after the parentheses), Internet Explorer displays the error message Line: 9 Char: 1 Error: Expected `)' Code: 0 and Navigator displays line 9: missing ) after argument list because the alert method is missing its closing parenthesis. If you run the code again after fixing this mistake, a final error is generated by the omission of the closing curly brace at the end of the function.

The Browser Says a Defined Object Is Undefined

This error is usually caused by having script reference an object before the object has been loaded or defined. You can resolve this problem in several ways. You can place your blocks of script in the HTML file after the element being addressed, or you can place all script in the head of the document but call it only after all objects have been loaded. The latter technique is often the preferred solution because it helps keep your code organized. To accomplish this, create an event handler that calls a function when the page has finished loading.

 window.onload=functionName; 

or

 window.onload=Function("functionName()"); 

or, in Internet Explorer only,

 <SCRIPT FOR="window" EVENT="onload"> {The script you want run, or a call to a function} </SCRIPT> 

Events Are Firing Unexpectedly

In Internet Explorer, this problem is frequently related to event bubbling (discussed in Chapter 7). For example, you might want to have something occur as the user moves the mouse pointer in and out of a table. If you simply add onmouseover and onmouseout event handlers for the table, these handlers will be triggered both by events that occur to cells within the table as well as by events that occur to the table as a whole. This is because the events that occur to cells bubble upward in the Object Model until they are handled by the parent object (the table). Code Listing A-3 and Figure A-1 demonstrate two examples of how this works.

Code Listing A-3.

 <HTML> <HEAD> <TITLE>Listing A-3</TITLE> </HEAD> <BODY> Notice that mousing between cells in the top table increments the number of mouseovers and mouseouts. <TABLE ID="A" BORDER="2"   onmouseover="F1.MOver.value=parseInt(F1.MOver.value)+1"   onmouseout="F1.MOut.value=parseInt(F1.MOver.value)+1">   <TR><TD>Cell1</TD><TD></TD><TD>Cell2</TD></TR>   <TR><TD>Cell3</TD><TD></TD><TD>Cell4</TD></TR> </TABLE> Notice that mousing between cells in the bottom table does not increment the number of mouseovers and mouseouts. Only mouse events on the table as a whole have an effect. <TABLE ID="B" BORDER="2"   onmouseover="if(!B.contains(event.fromElement))                  {F1.MOver.value=parseInt(F1.MOver.value)+1}"   onmouseout="if(!B.contains(event.toElement))                 {F1.MOut.value=parseInt(F1.MOut.value)+1}">   <TR><TD>Cell1</TD><TD></TD><TD>Cell2</TD></TR>   <TR><TD>Cell3</TD><TD></TD><TD>Cell4</TD></TR> </TABLE> <FORM ID="F1">   Mouseovers: <INPUT ID="MOver" TYPE="text" VALUE="1">   Mouseouts: <INPUT ID="MOut" TYPE="text" VALUE="1"> </FORM> </BODY> </HTML> 

click to view at full size.

Figure A-1. The two tables behave differently as the mouse movements interact with them.

In the first table created by Code Listing A-3, any onmouseout event received by the TABLE element causes the Mouseouts text field to be incremented. This is true whether the event was triggered for the TABLE element itself or for an element inside the table, such as a TD. If you move your mouse around in the top table, you will see the number of Mouseouts and Mouseovers increasing rapidly.

In the second table, the onmouseout event handler performs a test and increments the number of Mouseouts only if the event was not fired by an element contained within the table. In other words, the only element whose onmouseout event causes the background to change is the TABLE element itself.

NOTE
Some events do not bubble. If you are having problems with event bubbling, check the SBN Workshop Web site or the companion CD to ensure that the event in question does bubble. On the CD, see Workshop (References) and select DHTML, HTML & CSS; DHTML References; Events. To get to the online version, visit the MSDN Online Resource page at msdn.microsoft.com/resources/schurmandhtml.htm or open the file named MSDN_OL.htm on the companion CD, and choose Events.

An Image Is Displayed in Unexpected Colors

When a computer monitor is set to an 8-bit color resolution, it can display only 256 colors. For example, when a browser has the focus and has a GIF image loaded, it attempts to display the colors used in the image. If an image using a different palette is loaded, the colors in the browser are remapped to account for both images as well as the browser's palette. As a result, a palette flash might occur. Even if a flash does not occur, the image might not appear as intended because there might not be enough colors available to display all the colors in both images.

To avoid flashes or palette remapping, the image's palette should match the "browser-safe" palette (included on the companion CD in the Tools folder). This match is usually accomplished when an image is converted from high color (also known as full-color or 24-bit) to indexed color. Most image editing programs allow the designer to specify a palette when indexing an image.

Pages Take Too Long to Download

One obvious solution to this problem is to reduce the number of images on a page. That isn't always possible, of course, but it is nevertheless a good idea to evaluate the use of each image and consider whether it could be replaced with some other element. For example, before dynamic styles, often the only way to include stylized text or special text effects was to put the text in a graphic. Now that type of image can be replaced with HTML and styles, thereby significantly reducing download time.

The two most common graphics formats used on the Web are GIF and JPEG (the file extensions for these formats are .gif and .jpg, or .jpeg, respectively). Each of these two formats uses a different method of compression and thus is better suited for certain kinds of images. If your image has large areas of solid color, a GIF will usually provide the smallest file size. If your image contains a great deal of variation, such as a nature photo, a JPEG will usually produce the smallest size and best quality.

To illustrate these differences, we saved two images using the optimal format for each. You can see these images on the companion CD in the appxA folder. The first file, spots.gif, is less than 3 KB in size, and the image looks just as it should on screen. The second file, clouds.jpg, is 15 KB, and the colors in the image are smooth and bright. Now look at the same images saved in different formats.

Although the image spots.jpg looks fine, the file size is now 30 KB, 13 times as large as it was as a GIF. The clouds.gif file has expanded from the 15 KB JPG to 160 KB, and you can see severe color degradation and banding. It really pays to test different formats for your images.

Using the Structured Graphics control (discussed in Chapter 16) can also help to reduce the wait time for graphics when targeting only Internet Explorer. Structured graphics primitives can be especially helpful in replacing simple bitmapped images such as circles, squares, ovals, and so on.

Portions of an Image Cover Areas That Should Be Displayed

If you use GIF files for your images, you can make one color in the image transparent, which means that any element "behind" that image will show through the transparent color. Code Listing A-4 shows two different images in front of a background image, used in the body. Figure A-2 shows the result.

Code Listing A-4.

 <HTML> <HEAD> <TITLE>Listing A-4</TITLE> </HEAD> <BODY BACKGROUND="back.gif"> <IMG SRC="dhtml.gif" WIDTH=108 HEIGHT=26 ALT="" BORDER="0"> <IMG SRC="dhtmltrans.gif" WIDTH=108 HEIGHT=26 ALT="" BORDER="0"> </BODY> </HTML> 

click to view at full size.

Figure A-2. The second image uses transparent areas around the letters.

As you can see in Figure A-2, the first image completely blocks the background. The second image allows the background to show through around the letters. When we created the second image, we simply specified that white should be treated as transparent, resulting in the behavior shown. Typically, this is done when saving the file from an image editor.

Frames and Tables Don't Work

Frames and tables seem to cause headaches for many people. One common mistake is the never-ending frame. Content developers sometimes provide links inside a frame with no way to get out of that frame, resulting in a situation in which the same frameset is repeated, or the frames from two sites are mixed together.

The solution is to provide a way out of the frame by pointing links to the top window. For example, if a link points to www.w3.org, a direct link will open the page inside the current frame, wherever that might be. But adding TARGET="_top" to the anchor tag will open the page in the top window, replacing any frames on the page.

Another common problem is improper nesting. For frames to work, the FRAME elements should be nested inside a FRAMESET, as shown in the following code:

     <FRAMESET COLS="25%,*" FRAMESPACING=0 FRAMEBORDER="yes">       <FRAME NAME="frame1" SRC="frame1.htm" FRAMESPACING=0>       <FRAMESET ROWS="15%,*" FRAMESPACING=0 FRAMEBORDER="yes">         <FRAME NAME="frame2" SRC="frame2.htm" FRAMESPACING=0>         <FRAME NAME="frame3" SRC="frame3.htm" FRAMESPACING=0>       </FRAMESET>     </FRAMESET> 

In tables, cells (TD elements) must be nested inside an appropriate element, such as TR, THEAD, or TFOOT, which, in turn, must be nested inside a TABLE element. If your frames or tables are not displaying properly, check to see whether the content is nested correctly. Remember that you can use borders to test frames and tables, even if you do not plan to include borders in the final version. Using a border when you are creating your page can help you see exactly how the frame or table is displayed and can also help you debug the code when problems arise.

Pages Always Have Scrollbars, Even If They Are Not Needed

A standard Internet Explorer window is drawn with a scrollbar, and you might not always need it (for example, when there is no text on the page). Typically, this is not an issue in Netscape Navigator. You can eliminate the scrollbar by setting the SCROLL attribute in the BODY element to no. However, be careful when using this method because it completely disables scrollbars, meaning that users might be unable to access some of the page if their screens are in a lower resolution, or if they are using different fonts than you.

There are a few ways to make a scrollbar automatically appear only when necessary. If you are using frames on a page, you can set the SCROLLING attribute of a FRAME element to auto and a scrollbar will appear only if the contents of the frame extend beyond the borders of the frame. On a single Web page, you can enclose the entire contents of the page in one large DIV element that is 100 percent of the width and height of the screen and has its overflow CSS attribute set to auto. If you use this method, you will want to set the TOPMARGIN and LEFTMARGIN attributes of the BODY element to 0 and its SCROLL attribute to no to make sure that the DIV extends to the edge of the window. The following piece of code shows a portion of a file that uses this second method.

     <BODY SCROLL="no" LEFTMARGIN="0" TOPMARGIN="0">     <DIV STYLE="overflow:auto;width:100%;height:100%">     [The document content goes here]     <DIV>     </BODY>



Dynamic HTML in Action
Dynamic HTML in Action
ISBN: 0735605637
EAN: 2147483647
Year: 1999
Pages: 128

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net