| IDM | Client-Side Corner |
|
| Enriching the Intranet User Experience |
Engine Trouble
A Look at JavaScript in Microsoft IE vs. Netscape Communicator
By Chris Bonnici
Creating web content was supposed to be easy, and it is. The hard part is creating intelligent web content. On the client side, the strongest candidate for adding functionality to your pages is scripting -- JavaScripting, to be precise. Neither as powerful nor as complex as Java, both Netscape JavaScript and its near-twin, Microsoft JScript, can put a bit of automation into your site.
But as you've probably heard, there's a rub. Microsoft Internet Explorer (IE) and Netscape Communicator (like Navigator before it) support this powerful, wannabe standard language in different ways. Some of the differences might be glossed over as 'minor.' Others, I'm afraid, can make browser-independent web authoring hellishly difficult.
In this column I compare two popular browsers, MSIE 3.02 and Netscape Communicator 4.01, both in their Windows 95 incarnations. The bad news is that differences in how these products behave and handle scripting errors mean more complex solutions for the web developer. The good news is that with a little thought and practice, you can use JavaScript in a fairly portable manner. I'll show you how below through a series of working examples.
By the way, to see how each browser actually behaves, you need to have both MSIE and Navigator installed on your machine. If you do, great! If you don't, view the examples in your preferred browser and read the text to find out what the other half sees. Let's get started.
Loading a Page
The first example points up a significant difference in error handling between IE and Navigator. The error in question is trying to load a non-existent page.
As a baseline, consider first the error-free code below, which loads a page, waits five seconds, then jumps to another page. Try it.
<html>
<head>
<title>Loading a Page - Baseline</title>
</head>
<body>
<p>Before</p>
<script language="javascript">
<!-- begin script
var Delay = 5000;
document.writeln("<font size=4 color='#FF0000'><center>Please Wait. Loading Page.</center></font>");
// Wait 5 sec, then jump
setTimeout("window.location=’there.html’",Delay);// end script -->
</script>
<p>After</p>
</body>
</html>
For those new to the language, the HTML document below uses the <SCRIPT language="JavaScript"> …</SCRIPT> tag within the <BODY>…</BODY> tags to generate dynamic HTML code. The words BEFORE and AFTER are normal text strings within the HTML document, while the phrase Please Wait. Loading Page. is dynamically generated via JavaScript (tags and all). What does it do, you ask? The code waits a preset period, determined by the variable
Delay, after which a second HTML document is loaded.
Whose fault?
Now to introduce the error. Tryit02.html below attempts to load a document that doesn't exist (nothere.html). What happens when you try it depends on which browser you're using!
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<title>OOPS</title>
</head>
<body>
<script language="javascript">
<!-- begin script
document.writeln("<font size=4 color='#FF0000'><center><blink>Please Wait. Loading Page.</blink></center></font>");
setTimeout("window.location='nothere.html'",10000);
// end script -->
</script>
</body>
</html>
tryit02.html
In Communicator, the dialog box shown below pops up, informing you that the target file does not exist. But in Microsoft's browser, nothing happens. Five seconds pass, six, ten .... The user gets no clue that something is wrong.
Some might argue that it is the webmaster’s fault that the file does not exist. Granted, but shouldn’t both programs act the same?
Whether Netscape’s or Microsoft’s approach is a matter of continuing debate. Personally, I'd rather see a dialogue box telling me something's wrong than think the Web is running dead slow tonight.
Fun with Frames
The HTML document below shows a very simple example of frame creation. The code is discussed briefly so that readers who might be new to frames can follow the rest of the discussion.
<html>
<head>
<title>A Couple of Frames</title>
</head>
<frameset ROWS="*,50%">
<frame name="topFrame" src=frame01.html>
<frame name="botFrame" src=frame02.html>
</frameset>
<noframes>
Sorry, your Browser Doesn't Support Frames
</noframes>
</html>
Each frame is populated from a distinct web page. For instance, the code for the bottom frame is shown below:
<html>
<body>
<p><h1>This is the Bottom Frame</h1></p>
<hr>
</body>
</html>
frame02.html
The HTML code tryit03.html tells the browser that the page is to be split into two areas. The split is to take place row wise. The second frame is to occupy 50% of the screen area, the first one taking 'the rest' (designated by an asterisk). The two tenants of the window are topFrame and botFrame.
Frames are normally assigned top to bottom, left to right. In our example, since topFrame comes first it gets the penthouse area, while botFrame (second in the <FRAMESET> list) gets what remains (the ground floor screen apartment). Load tryit03.html into your browser. The text in each frame should make it easier for you to follow.
Look closely at the positioning of the two phrases in the two frames. They are not identical. The same source, but different formatting. We won’t delve into this subject here.
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<title>Frame File does not exist</title>
</head>
<frameset ROWS="*,50%">
<frame name="topFrame" src=frame01.html>
<frame name="botFrame" src=nothere.html>
</frameset>
<noframes>
Your Browser Doesn't Support Frames
</noframes>
</html>
The funny thing about this example is that frames aren't part of JavaScript. IE’s silence when it comes to loading non-existent objects apparently has nothing to do with JScript, but seems to be a fault -- er, feature -- of Internet Explorer itself.
What happens if we try to load a page that exists but is somehow defective? Tryit05.html is practically identical to tryit03.html the only difference being that in botFrame it calls a different document; frame22.html.
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<title><noframes></title>
</head>
<frameset ROWS="*,50%">
<frame name="topFrame" src=frame01.html>
<frame name="botFrame" src=frame22.html>
</frameset>
<noframes>
Your Browser Doesn't Support Frames
</noframes>
</html>
<html>
<body>
<noframes>
<p><h1>This is the Bottom Frame</h1></p>
<hr>
</noframes>
</body>
</html>
frame22.html
In this HTML file I’ve "mistakenly" inserted the NOFRAMES tags in frame22.html. Communicator seems to ignore this error and loads the document without any problem, while IE doesn’t display anything. From a strictly interpretive approach, IE's response is the 'correct' one; but the more verbose Netscape browser does come handy -- especially when reusing code from already defined libraries!
The above example is as much HTML as JavaScript. Another use of JavaScript is to create HTML coding dynamically within documents, as demonstrated next. The point is that many problems go unnoticed until one generates pages on the fly using JavaScript. Not being aware of these problems can make a JavaScript session tedious, laborious and far more costly.
Clear Out
The document below, tryit06.html, sets up two frames in the window. Try it.
The lower frame is loaded with color01.html while the top frame is left empty. When run, Communicator initially shows the contents of the directory while IE runs perfectly. This is a flaw in Communicator and should be addressed. We’ll expand on this in a moment.
Try clicking the link in the bottom window (winBottom). Communicator interprets correctly the instruction winTop.document.clear(), and clears the winTop frame. IE simply appends data to the previous writing.
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<script language = "javascript">
<!-- begin script
function rndNum(mod)
{
return (Math.round(639740*Math.random()+1) % mod);
}
function showLogo()
{
var outStr="Color Me Up";
var colorRed = rndNum(0xFF);
var colorGreen = rndNum(0xFF);
var colorBlue = rndNum(0xFF);
var decRed = rndNum(0x0F);
var decGreen = rndNum(0x0F);
var decBlue = rndNum(0x0F);
winTop.document.clear();
winTop.document.write("<center><h1>");
colNum = (colorRed-- * 0xFE01) + (colorGreen-- * 0xFF) + (colorBlue--);
winTop.document.bgColor = colNum;
for (var i=0; i<outStr.length; i++)
{
var colNum = (colorRed * 0xFE01) + (colorGreen * 0xFF) + (colorBlue);
winTop.document.write(outStr.charAt(i).fontcolor(colNum));
colorRed -= decRed;
colorGreen -= decBlue;
colorBlue -= decGreen;
}
winTop.document.writeln("</h1></center>");
}
// end script -->
</script>
</head>
<frameset ROWS="*,50%">
<frame src="" name="winTop">
<frame src="color01.html" name="winBottom">
</frameset>
<noframes>
Your Browser Doesn't Support Frames
</noframes>
</html>
tryit06.html
<html>
<body onLoad="parent.showLogo()">
<a href="#" onClick="parent.showLogo()">Click Here</a>
</body>
</html>
color01.html
Another noticeable difference between Communicator and IE is that IE will display the working-in-background mouse pointer when the cursor is moved over winTop. The toolbar Stop button doesn’t go off either. This does not happen in Communicator. The reason is that IE is still expecting the document in frame winTop to be closed.
Some might find this continuous frame updating a desirable feature. So how can we create this effect with Communicator? Simply remove the winTop.document.clear() line. Makes logical sense as well.
Example tryit07.html below alters the previous code to demonstrate this effect -- which, incidentally, is a great technique for a stopwatch program that displays start/stop times.
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<script language = "javascript">
<!-- begin script
function showLogo()
{
var outStr = new Date;
winTop.document.write("<center><h1>");
winTop.document.write(outStr.toLocaleString());
winTop.document.writeln("</h1></center>");
}
// end script -->
</script>
</head>
<frameset rows="*,50%">
<frame src="" name="winTop">
<frame src="color01.html" name="winBottom">
</frameset>
<noframes>
Your Browser Doesn't Support Frames
</noframes>
</html>
If you try placing the JavaScript commands winTop.document.open() (before the first document.write) and winTop.document.close() (after the last output instruction), IE will clear the frame just like Netscape. (The example tryit07a.html does just that). All seems to be working well.
We modified tryit06.html in a similar manner. The new document tryit06a.html does just that. Have we solved the problem? Yes, but we now have a new problem; background color. Communicator behaves well, unlike IE. In IE the background color flashes momentarily but always ends up being the default shade.
A solution that will work both with Communicator and IE is to include the background color within the <BODY> tag:
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<script language = "javascript">
<!-- begin script
function rndNum(mod)
{
return (Math.round(639740*Math.random()+1) % mod);
}
function showLogo()
{
var outStr="Color Me Up";
var colorRed = rndNum(0xFF);
var colorGreen = rndNum(0xFF);
var colorBlue = rndNum(0xFF);
var decRed = rndNum(0x0F);
var decGreen = rndNum(0x0F);
var decBlue = rndNum(0x0F);
colNum = (colorRed-- * 0xFE01) + (colorGreen-- * 0xFF) + (colorBlue--);
winTop.document.bgColor = colNum;
winTop.document.open();
winTop.document.write("<html><body bgcolor="+colNum+">");
winTop.document.write("<center><h1>");
for (var i=0; i<outStr.length; i++)
{
var colNum = (colorRed * 0xFE01) + (colorGreen * 0xFF) + (colorBlue);
winTop.document.write(outStr.charAt(i).fontcolor(colNum));
colorRed -= decRed;
colorGreen -= decBlue;
colorBlue -= decGreen;
}
winTop.document.writeln("</h1></center>");
winTop.document.write("</body></html>");
winTop.document.close();
}
// end script -->
</script>
</head>
<frameset rows="*,50%">
<frame src="" name="winTop">
<frame src="color01.html" name="winBottom">
</frameset>
<noframes>
Your Browser Doesn't Support Frames
</noframes>
</html>
You should notice that Netscape changes the background color twice in the code above. This is because we have not removed the winTop.document.bgColor = colNum; line (which IE ignores).
Even though there are now tools that help you develop and debug JavaScript one of the more efficient tools in debugging is to view the window (or frame source). This allows the developer to analyze the generated code. IE fares very poorly in this area.
In IE, right click on winTop. From the short-cut menu choose View Source. Notepad comes up with HTML that has nothing to do with what has been actually written. Repeat the same procedure in Communicator. A new window opens up and you get the source that was actually written to screen.
In IE a dynamically generated page does not seem to be registered anywhere and its corresponding reference is the document blank.htm. Netscape sets up this virtual page in wysiwyg://winTop.50/file:/D|/JScript/color01.html, with wysiwyg protocol.
There is not doubt that Netscape gets it right, while IE’s output only helps confuse the developer. Microsoft should address is flaw immediately. The only improvement I would like to see in Communicator is a facility that calls up a menu allowing one to wrap long lines and even open/save the frame. Another desirable feature is the ability to print the wysiwyg frame source window.
Press Me
If you are using Netscape Communicator, the next script provides the basis for a really cool links page. It provides a method whereby users can click on a button for more information. As it stands, IE will complain with an error. The problem line is identified as var winRight = window.open();. Solution: give IE the URL of the new window and it will work. Since we want an empty window, will provide a null value, i.e. var winRight = window.open("");. (Either alter tryit09.html yourself or load tryit09a.html). The onFocus event handler coupled with the blur() function doesn’t operate in IE.
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<title>Buttons</title>
<script language = "javascript">
<!-- begin script
function showData(who, webSite, desc1, desc2, desc3, desc4, email)
{
var mailTo = "mailto:" + email;
var winRight = window.open();
winRight.document.writeln("<html><body>");
winRight.document.writeln("<center><h1>" + who + "</h1></center>");
winRight.document.writeln("<br><br><p>" + desc1 + " " + desc2 + " " + desc3 + " " + desc4 + "</p>");
if (email != "")
{
winRight.document.writeln("e-mail address: <A href=" + mailTo + ">" + email + "</A>");
}
if (webSite != "")
{
winRight.document.writeln("<hr>");
winRight.document.writeln("<form name='mainForm'>");
winRight.document.writeln("WWW URL:");
winRight.document.writeln("<input name='theSite' type='text' size=50,1 value='http://"+webSite+"' onFocus='theSite.blur()'>");
winRight.document.writeln("</form>");
}
winRight.document.writeln("<form name='backUp'>");
winRight.document.writeln("<br><br><center>");
winRight.document.writeln("<input type='button' value=' Back Up ' onClick='window.close()'>");
winRight.document.writeln("</center></form>");
winRight.document.writeln("</body></html>");
winRight.document.close();
}
// end script -->
</script>
</head>
<body>
<form name="ca1">
<input type="button" value="More Info"
onClick="top.showData('M Web Magazine',
'www.geocities.com/~cbonnici',
'The M Home Page, house of the US mirror of the e-zine MWM. Many of the documents',
'in this site make extensive use of Javascript. Many not work properly with a browser',
'that does not support this scripting language.',
'',
'chrisb@4u.net')">
</form>
</body>
</html>
Something else you might notice about this example: as IE is building up the information window, the page flickers. Don’t adjust your monitor, the problem is IE.
IE doesn’t VOID
We don’t always want a click to act as a click; we don’t want the browser to take us to another area of our web or, for that matter, another site. Earlier on we used the <a href="#"> tag to achieve this, but with Netscape this gave us that momentary inconvenience of screwing up the display. Come to our rescue is the construct: <a href="javascript:void(0)>. This causes the link to have no jump-to action.
As demonstrated in tryit10.html below, this works fine with Communicator. Unfortunately, IE doesn’t like this command -- even though it interprets the
onClickpart of the tag. We know that the function was called because thealertinstruction in functionnewWin()appeared.
<html>
<head>
<meta name="Author" content="Chris Bonnici">
<title>VOID</title>
<script language="javascript">
<!-- begin script
function newWin()
{
alert ("Arrived OK");
return true;
}
// end script -->
</script>
</head>
<body>
<a href="javascript:void(0)" onClick="newWin()">Click Here</a>
</body>
</html>
I think ten-plus example of this sort is quite enough for one sitting, don't you?
Has this comparison been fair? I mean comparing Netscape Communicator 4.01 with Microsoft IE 3.02? Well at the time of writing IE 4 is still in beta and comparing a beta can introduce development bugs that will (or should we say should) not show up the in final release. Besides, all the code presented here will run on the previous version of Netscape, i.e. Netscape Navigator 3.x.
I take it on faith that all (most?) JavaScript developers want a solution that will:
- Allow them to develop a single solution for all JavaScript browsers;
- Expect the same results from identical code;
- Waste less time using navigator.appName to create dual-track solutions to the same problem, with attendant maintenance hassles, bugs, etc.
Believe me, there are plenty of other areas where the world's great browsers diverge from one another. I've begun compiling them for another article, hopefully to appear soon in IDM. Meanwhile, if you have a pet discrepancy not covered here, let me know at chrisb@4u.net and I'll try to include it. Till then, happy scripting!
About the Author
Chris Bonnici is the editor of the e-zine M Web Magazine (MWM), about the programming language M. He writes regularly for many paper and electronic publications, using JavaScript extensively in the web sites he designs. Reach Chris at chrisb@4u.net.
For more examples, a few popular JavaScript constructs can be found at:
- www.mcenter.com/mwm-us/. Utilizing cookies from within JavaScript, Chris has implemented an automatic bookmark. Second time visitors to MWM will be asked if they want to return to the page they were reading during their previous visit.
- http://www.geocities.com/SiliconValley/7041/links.html is the site from which most of the examples for this article have been taken.
- http://www.geocities.com/~cbonnici/dload.html and http://www.geocities.com/~cbonnici/ftpserv.html are other examples of code creation using JavaScript.
[ Archive | Current | F A Q | Find | comment? ]
Copyright 1996-97 by Mecklermedia Corp. All rights reserved.