JavaScript FAQ
This FAQ is a work in progress by Andy Augustine. If you are viewing this from a mirror site, the original and most recent version of this document can be found at http://www.freqgrafx.com/411/jsfaq.phtml.For specific Q&A on Netscape 3.0 (which is still in beta), check out the ATLAS/JavaScript FAQ. Netscape has released Navigator v2.02 to fix some JavaScript security issues (among other things). Make sure you get it and use it from now on.
If there is a topic that you think should be added to the list you can use our submission form or post it to one of the following groups and I will add it. Listed here are a collection of answers, hacks, workarounds, and kludges that have been taken from the:
- Netscape Development Partners Program
- JavaScript mailing list.
- Ask The JavaScript Pro
- comp.lang.javascript
Other than JavaScript 411, links to a variety of JavaScript pages on the Web can be found at Andrew Wooldridge's JavaScript Index site. If you have found your way here, I assume that you've already tried to find the information you need from Netscape's Official JavaScript Docs. NOTE: the Netscape docs that were zipped up and on-line are gone! Looks like anyone who didn't get them in time will have to buy their book when it comes out.
SECTION I. Some basics you must know before proceeding!
- HEIGHT and WIDTH tags for images
- Where does the SCRIPT go in my HTML?
- How do I load a JavaScript library without embedding it in my HTML?
- How do I print a frame generated by JavaScript?
- How do I define a variable as global/local?
- How do I use the <APPLET> tag?
(a.k.a Java/Javascript Integration?) - Can I do animations with Javascript?
- What kind of size limits are there for the scripts that I write? (64k on Win3.1)
- Why do long strings generate the 'Unterminated String Literal' message?
- I pass a variable to the parent/sibling frame, and it's fine. But when the passing frame unloads, the value gets corrupted. What's the fix? (Fixed in Navigator 3.0)
- Eval() crashes Navigator on Windows 3.11 in 2.0b6 or later. (Fixed in Navigator 3.0)
- When I call window.open(), a new window is created but it's empty.
- On some X platforms, boolean options for a new window may be ignored.
- Why is my array of radio buttons indexed in reverse order?
- Math.random doesn't work on platforms other than X. (Fixed in Navigator 3.0)
- The click() method doesn't work.
- The onSelect() event handler is broke for TEXT and TEXTAREA.
- The copyhistory boolean has been disabled for window.open() due to security reasons.
- I get strange numbers returned from parseFloat() and the % operator.
- When I modify document.bgcolor the text on my page disappears.
- Why can't I use: document.write('</SCRIPT>')
- The window.defaultStatus property is broken on some platforms (like Win95).
- RELOAD button: how do I make a button that will reload the current document?
- When I use myRadio.value, the value is always <undefined>.
- How do I cancel the submission of a form if the user input was invalid?
- How can I control the size of the buttons I create?
- JavaScript does not support <INPUT TYPE="image"> form objects.
- Hidden fields won't retain their value across a reload/resize.
- You cannot evaluate of modify values entered into password fields!
- BACK button: how does one frame make the other go back a page?
- What is the best way to synchronize the loading of frames in order to avoid JavaScript error messages?
- I've used window.open() to create a new window. How do I reference my original window from the new one?
- I've got a page that uses frames, how do I make a link that will come up in the whole window, erasing the frames?
- How do I create a link that will update multiple frames?
- What security risks are inherent in JavaScript?
- How do I use JavaScript with Client-Side Image Maps?
- How do I automatically redirect visitors to the right page depending on whether they can/can't use JavaScript?
- What happens when I recursively call setTimeout()?
- How do I detect if a user has a certain plug-in?
SECTION I. JavaScript Basics before you start
There are several things about JavaScript that seem to slip past most newbies. Either they aren't documented correctly, or they are documented but just not where you'd think to look for them. Before you post a question to one of the groups above, you should consult the 'Known Bugs' list for your operating systems version of Netscape 2.0. In Windows you can find it in the Help menu under Release Notes. (On the Mac you can pull it down from the '?' menu.) If you've looked elsewhere and can't find the answer you need, read on!
---------- <HTML> <HEAD> <TITLE>Example</TITLE> <SCRIPT LANGUAGE="JavaScript"> <!-- HIDE FROM OLD BROWSERS code goes here // --> STOP HIDING </SCRIPT> </HEAD> <BODY> HTML goes here </BODY> </HTML> ------------
[Answer: Brendan Eich]
function f() { x = 3; ... } ^^^^^where x is unbound when f's definition is parsed. The bugs may lead to wrong answers, but should not crash you (I think).
You should say what you mean here. If the intent is for x to be local, you must use var before it. To avoid trouble, you may choose a style where you always use 'var' to introduce new variables whereever you need them. If you are writing a function that wants local variables (or needs them, if it is recursive), use var. If you want to use a global in a function, make sure there is a top-level var statement that introduces the global before the function definition:
<SCRIPT LANGAUGE="Javascript"> <!-- hide from old browsers var x ... function f() { x = 3; var local = ... } // done hiding --> </SCRIPT>
If you're looking to call a JavaScript function from within a Java Applet, you can use this call (submitted by Achille Hui):
showDocument("javascript:/**/myJSfunction()"It appears that the /**/ is necessary to call 'myJSfunction()' instead of '/myJSfunction'. If you're interested in how Javascript reference Java in the future (Navigator 2.1), Brendan Eich wrote:
Statement of work in progress for 2.1: You will be able to get and set Java public static fields as if they were JavaScript properties of an object named after the package-qualified class name, and call Java methods that are public, provided you can reach their instances from the top-level Applet context thing. In JavaScript, you name an applet via either document.applets[myAppletIndex] or document.myApplet where a NAME attribute has been used. The reflection of public fields and methods from Java into JavaScript will be automatic and lazy.
- Use a Java applet that loops gifs.
- Use an animated GIF89a!
--(but don't expect onMouseover to initiate any action!) - Create a small corner frame (picFrame) and use onMouseOver or setTimeout() and
parent.picFrame.location = pic1.gif (pic2.gif)
- Redraw the entire page with doument.write() and the new image.
SECTION II. Known Bugs and Workarounds
Although JavaScript development has come a long way in a short time, there are still a few glitches that can tie up your projects if you're unaware of them. Some of these bugs only occur on one platform. However if your system is not affected by one of those listed below, you must keep in mind that everyone viewing your pages with the afflicted platform will run into difficulties and possibly even crash. You should try and familiarize yourself with all of the problems below to make sure you're not writing buggy code.
var mystr="This is an example of a very long sting that is just like a run-on sentence and may break the code. Somebody suggested theres a 254 character limit for Windows 3.1 so this example is an attempt to be at least that long. I don't know who would simply define a string this long, but there are times when it's necessary."you should break it into smaller peices on sepeareate lines using the + sign to concatenate it. The fix would look like this:
var mystr="This is an example of a very long sting that is just like a run-on sentence" + "and may break the code. Somebody suggested theres a 254 character limit for" + "Windows 3.1 so this example is an attempt to be at least that long. I don't" + "know who would simply define a string this long, but there are times when it's" + "necessary."
This bug has been fixed in Navigator 3.0 with the introduction of the String object. You can now pass String objects between frames and windows without worrying about the 'weak link' bug described above. To create a String object use the 'new' keyword:
var msg = new String("This is a string object")
If you're still interested in the fix for older browsers, this will work for
Navigator 2.x: [Answer: Bill Dortch]
** parent ** var myvar = "" function setvar (value) { myvar = "" + value; // create new string in parent context } ** child ** parent.setvar("myvalue");
[Answer: Bill Dortch]
if (navigator.appVersion.indexOf("Win16") == -1) { // not Win16 eval (...); // evil!!! } else doSomethingElse();
var newWin = window.open(myURL,'myWin') if (navigator.appVersion.indexOf("(X11") != -1 || navigator.appVersion.indexOf("(Mac") != -1) newWin = window.open(myURL,'myWin')The trick here is to call window.open() a second time to force the load.
<FORM NAME="radioTest"> <INPUT TYPE="radio" NAME="testset" VALUE="A" onClick="">A <INPUT TYPE="radio" NAME="testset" VALUE="B" onClick="">B <INPUT TYPE="radio" NAME="testset" VALUE="C" onClick="">C </FORM>Here's proof that it works:
If you would like to modify the colors on your page using JavaScript, one way to do it is to store the values you would like to use as cookies and then reload the page, using JavaScript to write those attributes of the <BODY> tag from the stored cookie values. To test the bgColor property on your platform, try my example page in the tutorial section.
SECTION III. Dealing with Forms
function validate() { if (**test for valid input**) return true else return false } ... <FORM onSubmit="return validate()">NOTE: you do not return false from the SUBMIT button's onClick handler! The former is sufficient and relieves you from having to write N onClick handlers if your form has N submit buttons -- you write an onSubmit handler once in the <form ...> tag.
This should be fixed with the release of Navigator 3.0 from Netscape which will include a 'data tainting' model which will allow scripts to see the value but limit where it can be sent off to.
SECTION IV. Frames and Windows
One of the most dynamic uses of JavaScript is in conjunction with Frames. You can make cross-frame calls to functions/objects/variables in separate frames by simply calling something like the following:parent.myframe.myobj parent.myframe.myfunction(mylocalvariable)Note that when you call a function in another frame, the scope of the parameters that are passed is local to the calling frame. If you want to call a function on a element in another frame, you could use something like:
mylocalfunction(parent.otherframe.myvariable) parent.otherframe.myfunction(parent.otherframe.myvariable)and explicitly declare which frames you are referencing.
<FRAMESET COLSPAN="50,*"> <FRAME src="/tutoriales/manuales/htmldocs/navigationbar.phtml" name="nav" NORESIZE> <FRAME src="/tutoriales/manuales/htmldocs/mainframe.phtml" name="info"> </FRAMESET>Then you could put this code in your navigationbar.phtml page to manipulate the info frame:
<FORM NAME="buttonbar"> <INPUT TYPE="button" VALUE="Go Back" onClick="parent.info.history.back()"> <INPUT TYPE="button" VALUE="Go Home" onClick="parent.info.loaction="home.phtml"> <INPUT TYPE="button" VALUE="Go Next" onCLick="parent.info.history.forward()"> </FORM>Alternatively, you could use the history.go(-1) and history.go(1) functions, as stated in the Netscape docs. Also look at the Reload button
in order to avoid JavaScript error messages?
[Answer: Brendan Eich]
Sure, you can synch framed JavaScript execution to start only when the whole frameset is loaded, but you have to write some JavaScript to do it. In the top-most FRAMESET's ONLOAD handler, you can set a variable or property of that window ("self.loadDone = true"). In all descendent frame documents, you can make their first SCRIPT tag (or if there are no SCRIPT tags only event handlers, in their BODY or FRAMESET tag's ONLOAD handler) call the following function: function topWait(expr) { if (!top.loadDone) { // XXX expr had better not contain unescaped single quotes! setTimeout("topWait('" + expr + "')", 500) } else { eval(expr) } } to do whatever work (expr, a string containing JavaScript code, most likely a call to the "main" function for that document) needs to be done only after the whole frame tree is loaded. There are more complicated schemes that involve code in different frame documents being very careful to test (parent.otherframe.forms != null && parent.otherframe.forms.length == 2), e.g., and not look for properties or members of such object references until the test succeeds.
How do I reference my original window from the new one?
var popWindow = window.open(myUrl,'myWindow') popWindow.creator = selfNow you can reference the original window and all its properties/functions/... from 'myWindow' with standard Javascipt syntax:
***code goes in popWindow's source*** creator.document.myform.myfield.value = aNewValue;Be sure you're aware of the known bug with window.open().
<A href="/tutoriales/manuales/htmldocs/mypage.phtml" TARGET="_top">Go to my non-framed page</A>
SECTION V. Using arrays
Netscape Navigator 3.0 will support a new object of type 'Array'. To create an array in 3.0, you can use any of the following:
var tmp = new Array() // creates a new empty array object
var tmp = new Array(5) // creates an array with (tmp.length==5) and elements (tmp[0]..tmp[4]) all set to null
var tmp = new Array("hi", 15.3, myVay) // creates a 'dense' array with (foobar.length==3) and elements (tmp[0]..tmp[2])
To set an array's length, there's two chances for doing it: when you call the constructor, or anytime thereafter. To set the length when the array is initialized, use:
var myArray = new Array(5)NOTE however that you cannot directly set myArray.length with an assignment statement as it is read-only. If you'd like to change the array's length after it's already been created, you have to add an element to the array like this:
myArray[9] = "This is the 10th element."By adding an element in the Nth spot, you're forcing the arrays length to N+1. In this last example, myArray.length would now be set to 10.
SECTION VI. Advanced Topics
This section will deal with concepts like efficient memory usage, arrays, and security problems to name a few.Here's the current list of security holes and their status: 1) Read user's history -- fixed in 2.0 2) Read user's URL cache -- fixed in 2.0 3) Forge e-mail/steal e-mail address - fixed IN 2.01 4) Recursively list local disks - fixed in 2.01 5) Open 1 pixel window and log all URL accesses - STILL PRESENT IN 2.0Netscape has done a fine job of handling security related issues with the release of Navigator 2.01. I have left the links to the *old* pages that exploited Navigator 2.0 so that users can test the fixes in 2.01.
The ability to forge e-mail/steal e-mail address from a visitor has been cut-off by disabling the submit() method on a form which has been defined as: