Netscape Network ad
____________________

11 JavaScripts & tips you asked for

Keen advice you never knew you needed, a handy JavaScript/VBScript comparison chart, & answers to reader mail

By Lisa Rein

NetscapeWorld
has become
[Netscape Enterprise Developer Table of Contents]

June 1997
[June 1997 Table of Contents]Table of Contents
[Archives]Topical Index
[Search]Search

Summary
This month, we're offering practical scripts, a host of non-documented details you won't find in books or any standard documentation, and answers to more of your questions, while asking a few questions of our own. Unless specifically stated, these should work on Windows 95 and NT, 68000 and Power Macintosh, most Unix versions, and both Netscape 3 and Internet Explorer 3. (2,200 words)

First we have a sturdy, standard converter script, a user confirmation window, tips for keeping your content from being "framed," a technique for keeping your JavaScript windows on top of the cascade, a reminder about which words shouldn't be used when naming your variables, details about including external JavaScript files, tricky stuff including writing to one frame from another, generating random content in tables, and more. We also offer our first installment of a VBScript-to-JavaScript conversion series.

This page's table of contents
Basic conversion script
User-confirmation script
Unframing your content
Keeping windows on top
Reserved words- naming variables
A random function with a tabulated twist
Dynamically updating BODY attributes
Including JavaScript files
Troubleshooting errors with soundOnload
Writing to one frame from another
VBScript/JavaScript comparison table
Resources

Basic conversion script
This basic conversion script is a pretty straight-forward example of declaring variables, assigning values, and using the basic transitive properties of equality operators to perform simple conversions. If you'd like to brush up on your transitive property theory, check out this section from "JavaScript 1.2's evolution as explained by its creator" in the May 1997 issue of NetscapeWorld.

See convert.html in action.

Too close for comfort: how to not name your variables
What was initially interesting about this conversion script was that it brought out a common problem that often occurs when naming variables.

When I first encountered the script, something strange happened when I tried to use its "C" clear button.

Check it out for yourself, but you'll have to use your Back button to return here.

See convertdud.html in action.

Hint: look at this code snippet:

function clear (form)
This appears twice in our script, and is the culprit.

It turns out clear is close enough to clearTimeout, one of those reserved words that you shouldn't name your variables when using JavaScript. To fix the problem, we had to rename both references to clear (form) to clearr (form). That did the trick.

A user confirmation window
This user-confirmation script will bring up a little alert box that the user will have to acknowledge before entering another area of your site. You may want to warn the user about content, pester the user about a plug-in the page will require, or just show-off.

If the user clicks "Yes" they will continue on to the next page. If they click "No" they are kicked back to whatever page they were on.

The only tricky thing about this function seems to be a line length limit on the amount of text you can put in the alert window. There doesn't seem to be an official length limit listed anywhere, so I filled in as many words as would fit.

See confirmation.html in action.

Unframing your content
"Framing" is the practice of displaying someone else's Web page in a frame on your page. (See "It's OK to put a link to another site on my page, right? Maybe not" in Rick Cook's June 1997 "Best Practices" column in NetscapeWorld.)

When I first looked into this problem I got the following advice from several pages: "Just use the META tag with the reload action to load your page, and mark it with a target=_top attribute." But it turns out this isn't a good idea, because if you have a page refreshing to itself it will loop endlessly, refreshing every X seconds.

Here's a quick fix that will work, but it will limit the use of frames on your own site in the process.

This comes from reader Hal Pawluk, who's got a nifty site with a lot of good advice on it. He got his tip from the newsgroups, and it goes like this:

"Just put this in your HEAD tags, and remember, if no one can frame your pages, that means you can't either (people forget that, I swear):"

<SCRIPT>
   // DON'T USE IN PAGES YOU WANT 
  // TO DISPLAY IN FRAMES

if ( top.frames.length > 1 )
        top.location="/";
</SCRIPT>

Besides keeping your content on your site, it makes certain your page looks the way you intended it to look. I've seen off-site content jammed into a frame so tightly that text was over-writing graphics. (Actually a nice trick if you could control it, but you can't.)

As Pawluk explains, "nothing works with Explorer because it simply doesn't understand focus(). I've tried everything, including closing the window in the background and trying to create a new one, but Internet Explorer choked on even that."

To learn more creative fixes for this problem, see "The best way to FRAME-proof your pages" in Chuck Musciano's May 1997 "HTML Q&A" column in NetscapeWorld.

Keeping windows on top
If a pop-up window is open in the background, Netscape and some iterations of Explorer won't automatically bring it to the front but instead just write the new content where nobody can see it, so it looks like the links aren't working.

You can fix that for Netscape (no fix for Explorer) by adding one instruction to the newPopwin() function. (This is based on a tip from a person named "deshddude," who posted this in a JavaScript news group.)

function newPopwin(page){
Popwin = window.open(page,'', 
      'width=460,height=360,scrollbars=1,resizable=1,'+
        'menubar=0,toolbar=0,location=0,directories=0,'+
         'status=0,copyhistory=0');
 if (Browser == 'Netscape')    // hide from Explorer
            Popwin.focus();
    }

This worked on my machines, but your real-life implementations will be the only way to determine if these methods are working consistently. Please let me know what you find.

Dynamically updating BODY attributes
A reader recently sent us this question:

Is there a way you can change the color of the text on the links using on mouseover when the mouse is over them? (as opposed to the color of the background or images).

Then another reader suggested the following solution:

I teach basic HTML development for the Center for the Application on Information Technology at Washington University in St. Louis, Missouri. I like your JavaScripts and they gave me some ideas.

I created some simple JavaScript functions to interactively change a document's background, text, link, active link, and visited link colors.

Then I created some forms with menu pulldowns with the 16 basic colors as defined in HTML 3.2, actived by onChange. The background color changer will work, but none of the rest will.

Any ideas on what may be the problem? I checked it with Internet Explorer 3.02 and works perfectly. -- Eduardo Gomez Maqueo

See onchange.html in action.

The real question on this one shouldn't be "why does it not work in Netscape?" but "why does it work with Internet Explorer 3?"

In JavaScript, the only dynamically updatable attribute is the document.bgcolor property. Others are rendered on full-page loading only.

The only things that can be dynamically updated via JavaScript in an HTML page are:

  1. text and textarea forms elements
  2. images (in Navigator 3 or later)
  3. BGCOLOR attribute

Of course you can always force a load into another frame, or use Java, but the learning curve is three to six months instead of JavaScript's three to six weeks.

One interesting thing though, when tested, the active link did change in Navigator.

Now, in Internet Explorer they ALL do work -- except Internet Explorer doesn't do "active link" color change at all. It appears as though Internet Explorer made all of the elements accessible.

By the way, the above is true in both 3.x versions on Windows 95.

Including JavaScript files
I just read your article/interview with Brendan Eich; I found it enormously helpful. Thanks!

One issue I did not see covered there was the inclusion of JavaScript using <SCRIPT SRC=xxx.js>, a feature not supported by some new versions of Internet Explorer 3 even though they claim to read JavaScript 1.1. My JavaScript work depends on this kind of inclusion, though I've noticed some peculiar behavior in Navigator 3 regarding this.

Do you have knowledge of how this aspect of JavaScript is evolving, or perhaps where I might find details, bugs, or special aspects of its implementation in JavaScript1.1? -- Rhett

We also received this letter:

Is there a way to call JavaScript code that's in another file? It would make it easier to reuse the same JavaScript for multiple pages. -- Steve Duran

There are several for including JavaScript files externally. A JavaScript file can be used by more than one .html file at a time, and is cached by the browser, making things load more quickly. It can also simplify your files by allowing you to remove large blocks of code from them.

One uses the SCRIPT tag with the SRC attribute like this:

<SCRIPT SRC="filename.js">
//place comments here if you like
//and don't forget your end tag
</SCRIPT>

Here are a few things to remember when using .js files and the SRC attribute:

Troubleshooting errors with soundOnload
We have been trying to use JavaScript soundOnload. We are using Hot Metal Pro to create our Web site. It works fine on our hard drive, but when we load up our Web site it gives us the following message:
NPP_StreamAsFile():
frame is NULL
This probably means that your disc cache is too small.

Could you please help us with this. -- Sue

The first thing that comes to mind is to find out the exact syntax of the event handler you wish to call. Is it "soundonload" or "soundOnload"? Remember, JavaScript is case-sensitive so it's going to have an effect on the end result.

A more probable possibility is that perhaps the "onload" event handler is invoking before your frameset is fully loaded. If your network connection were to stall, for instance, after a button appeared but before the parts of the document that the button relied on were loaded, you'll get the kind of error message you describe.

To prevent this from happening, you can set up a way to "check" that it is loaded before executing the handler. Set a variable "checked" to "true", and then make sure that variable's value is "true" before executing any handlers whose fate depends on it.

Another, non-JavaScript possibility for the error message is that your server isn't configured to handle that sound file format or perhaps to work with a specific plug-in. If you know that's not the case because you've played that format of sound from your server before, then it's probably just a path problem. Double check to make sure your HTML file is calling to a proper sound file, and not a directory that contains other formats or data types.

But if the paths check out, look in your server's manual for the name of its mimetype file, and look in there to double-check which MIME-types it is configured for. To do this for Netscape servers, for example, you will be looking in a file named "mime.types". There will be an entry for both the type of file and any extensions associated with that type.

Here is what a typical entry in this file looks like:

type=audio/x-midi  exts=midi, mid

One of those fixes ought to help your situation. Remember to give as many details as you can when you submit a bug report or a ask a technical question. What formats were involved? What platform were you using? Exactly what version of which browser, and which version of JavaScript were you trying to invoke? Those kinds of details make all the difference when troubleshooting just about anything.

Creating a frameset and its content from another frame
This one we got from the newsgroups, along with the answer provided by Brendan Eich, JavaScript's creator.

I want to have the content for a frame within the actual frameset page. How do I have one page create the frameset and content for one of the pages.

Set up an onLoad event in the <FRAMESET onLoad="myfunc()"> tag.

Write your <FRAME> tags to just load a blank page <FRAME SRC="about:blank" name="mypage">

Then in a JavaScript function, open the document and use JavaScript to write the HTML:

 function myfunc() {
  top.mypage.open();
  top.mypage.writeln("<BODY>");
  top.mypage.writeln("Hello, world.");
  top.mypage.writeln("</BODY>");
  top.mypage.close();
 return;
 }

Or another way that's often more efficient:

<SCRIPT>
. . .
var mypageSource = "<BODY>Hello, world.</BODY>"
</SCRIPT>
<FRAMESET ROWS=...>
<FRAME NAME=mypage SRC="javascript:parent.mypageSource">

</FRAMESET>

A random function with a tabulated twist

Editor's note: Special thanks for this section to MegaZone, who helped me explain it in english!

First, see what we're dealing with in this example.

This function randomly picks a list of words from the array by moving the index. Then he builds a table with the randomized list.

Fill an array.

<SCRIPT LANGUAGE="JavaScript1.1">
<!--for (var i = 0; i < bingowords.length; i++) {

Var is 0 (first position in the array, zero ordinal, up to the last position in the array.)

temp = bingowords[i];
Stick the word in a temp variable.
j = Math.round(Math.random() * bingowords.length);
Set j to be some random number within the range of the array.
bingowords[i] = bingowords[j];
bingowords[j] = temp;
Swap words.
bingowords[Math.floor(Math.random() * 25)] = "<FONT
COLOR=#FF0000>BINGO</FONT>";
Randomly insert the word BINGO!
for (var i = 0; i < 5; i++) {
   document.writeln ("<TR VALIGN=TOP ALIGN=CENTER>");
   for (var j = 0;  j < 5;  j++) {
     document.writeln ("<TD>",
          bingowords[i*5 + j],
          "</TD>");
   }
   document.writeln ("</TR>");
}
Build the table using just the first 25 words of the randomized array.

The more words in the array, the better.

The similarities and differences between VBScript and JavaScript
This first installment of our VBScript/JavaScript conversion series is aimed at helping Windows-centric developers make the transition to JavaScript (only up to version 1.1, to ensure compatibility with both Internet Explorer and Navigator), while helping JavaScript-ers prepare for this new age of Cascading Style Sheets. The goal is to explain and demonstrate how to achieve the same spectacular enhancements once thought to only be possible with VBScript and CSS with JavaScript and CSS.

Ideally, we should be able to come up with a JavaScript/CSS solution for creating dynamic content that works great in both major browsers, and gracefully degrades down through their corresponding older versions. Your feedback and participation will be very important to the sucess of this endeavor, so if you have any tips, corrections, or comments, send them in.

VBScript/JavaScript comparison table
FeatureVB ScriptJavaScript
Language based onVisual BasicC++
Language InterpreterInterpreter and object model separateIntegrated into browser and object model
Placement of ScriptBetween <HEAD> tags <HEAD> tags
Object architecturerelies more on built-in functionsrelies on objects and methods and properties
Strings
string object -- automatically exists
Creating and loading variablesDim buffer
buffer="vbscript"
var buffer
"javascript"
Determining lengthcalls the Len() function
length=Len(buffer)
string object's
length property
len=buffer.length
Extracting a single characteruse Mid() function
char=Mid(buffer,5,1)
char=buffer.charAt(5)
Case sensitivityNOT case sensitiveCase sensitive
CommentsRem and '//
Examples of commentsThis is a comment
Rem this is a comment
document.write : Rem can be used now
// this is a comment
//this is another one
Handling of Data TypesOne type: VariantNumeric, strings, boolean

Resources

About the author
Lisa Rein is the associate editor for NetscapeWorld. Reach her at lisa.rein@netscapeworld.com. HYIP Monitor