Important warning: Do not use the JavaScript redirects described in the section headed "Forcing a page to appear in a frameset"! If you do, your site may be banished from the Google index, because similar redirects are used by some sites in order to manipulate rankings in the search engine. The methods described here are in fact harmless and non-deceptive, but you should avoid using them because similar methods have been misused by other web authors, and you will suffer the consequences of their misdeeds.
The other techniques on this page (used for closing a popup window and for text-only dynamic menus) should not cause problems with Google's index. The only dangerous techniques are the ones in the section about frames and framesets.
Notes on the JavaScript and Dynamic HTML formerly used on this site
Some of the JavaScript and Dynamic HTML formerly used in this site may be of interest to web authors. The notes below explain some of the JavaScript that makes the site more manageable and convenient for users, but doesn't call attention to itself. Further notes will be added in the future about other JavaScript on this site, with fuller details about the Dynamic HTML used in the navigation frames used in version 4 and later browsers. The JavaScript on this site is apparently compatible with with Internet Explorer 3 through 6, Netscape 2 through 4 and Netscape 7, and uses workarounds to avoid serious incompatibilities with Netscape 6 and Opera. It also appears to work with Safari for the Macintosh and all recent (post-2001) Mozilla-based browsers. Note that "Forcing the keyboard focus into the right-hand frame" works only intermittently in Netscape 6, but this failure is merely an inconvenience.
Forcing a page to appear
in a frameset
Forcing the keyboard focus into the right-hand frame
Closing a popup window when the opening
page is closed
Text-only dynamic menus
Forcing a page to appear in a frameset (see the important warning at the top of this page)
Many of the pages on this and other frame-based sites are listed individually in search engines; these pages use JavaScript to force the page to appear in a frame, with the navigation frame also displayed, even when a visitor opens a link to the individual page itself. (Without the JavaScript, the page would open in the full browser window, and no navigation frame would be visible.) Many web sites use simple scripts to force a page into a frame, but most such scripts require the web author to create a separate frameset for each page on the site. The script used on this site avoids this difficulty by generating a frameset as needed and forcing the page into the frameset.
A familiar problem with pages forced into a frameset is that they cannot normally be printed in NN4 because when this Netscape version prints a page, it first loads it into an invisible frame; if the page is then replaced by a frameset, Netscape has nothing to print because it tries to print the frameset, not the page inside one of the frames. Some sites solve this problem by providing a link to a "printer-friendly" version of the page. The script used on this site solves the problem without requiring two versions of the page.
The script combines ideas and code fragments from five programmers. Steve Pruitt
created the generic script that tests whether the current document has two frames,
and, if not, creates a new frameset on the fly; but his code was incomplete
until Christopher Thompson suggested loading a blank.html file in the
second frame before reloading the original page. The substitution of about:blank
for blank.html (in some browser versions) was suggested by Martin Webb;
this substitution is made only in version 4 browsers because of problems pointed
out by Danny Goodman; the code that solves the problem of printing pages in
NN4 is adapted from work by Martin Webb and Jan Ehrhardt, as is the use of the
Because this code (and similar code attempted by other authors) does not work in Netscape 6 or Opera (before version 7), a different solution is used for these browsers. When a visitor opens a specific page listed in a search engine, Netscape 6 and Opera (before version 7) open the main page of the site. The visitor must find the page he or she originally wanted, but this is better than facing a blank window or an error message, which is what Netscape 6 and Opera (before version 7) would do otherwise.
After this script was mostly complete, I learned of a more elaborate and thoroughly tested solution by Martin Webb and Jan Ehrhardt which is documented at irt.org. Their script requires only a few lines of code in each of the framed pages and a lengthy script in the frameset page, which is a more bandwidth-efficient method than the one offered here, although perhaps more complicated to implement. As noted in a preceding paragraph, two details of this site's script were adapted from the Webb-Ehrhardt solution in order to replace similar details in an earlier version of the script below.
<script language="javascript" type="text/javascript"> <!-- // Start by reducing the name of the browser to lower case // for easier handling: var agt=navigator.userAgent.toLowerCase(); var appVer = navigator.appVersion.toLowerCase(); // For this code to work, you need a blank.html file, which can // contain only the tags <HTML></HTML> (and probably even // less, but use this minimum for safety). // Pre-version-4 browsers use blank.html because about:blank // is unsupported in MSIE3, and, when used with NN2/3 for the // Macintosh, causes spurious text to appear in the window that // loads next (this information from Danny Goodman). It seemed // more trouble than it was worth to test only for Mac versions of // NN2/3, so blank.html is used for all earlier browsers. The // about:blank method is preferable because the browser does not // need to take time fetching and loading a file. if (parseInt(navigator.appVersion) <= 3) { var srcStr = "blank.html" } else { var srcStr = "about:blank" } // The frameWriter() function does the work of writing out the frameset. // The variable srcStr is replaced with "blank.html" or // "about:blank" when the code is written to the document. // The final <\/HTML> tag may not actually get written in some // browsers, but it is good form to use it. (The backslash preceding // the forward slash is required by recent versions of HTML.) function frameWriter() { // If the browser is NN6, do not attempt to write out the frameset. // Simply go to the main page of the site. It's better than nothing. if (agt.indexOf('mozilla')!=-1 && (navigator.vendor)&& (navigator.vendor=="Netscape6") && parseFloat(navigator.appVersion) == 5 && (!window.opera)) { location.href = 'index.html' } // If the browser is any version of Opera earlier than version 7, // also do not attempt to write out the frameset. Versions of Opera // before version 7 will not use relative links when replacing // the location, so use an absolute link instead. (But see note // above about continuing problems with Opera.) else if ((agt.indexOf("pera") !=-1) && agt.indexOf("7") != 1) { location.replace("http://audensociety.org/index.html"); } // But if we are not in NN6 or Opera pre-version 7, we can write // out a frameset. else { document.write('<FRAMESET COLS="104,100%" FRAMESPACING="0"'); document.write(' FRAMEBORDER="0" BORDER="0" onLoad="FrameMe()">'); document.write(' <FRAME SRC="contents.html" NAME="menuFrame"'); document.write(' SCROLLING="no">'); document.write(' <FRAME SRC="'+ srcStr +'" NAME="contentFrame")'; document.write(' NORESIZE>'); document.write('<\/FRAMESET>'); document.write('<\/HTML>'); } } // The FrameMe() function replaces the blank page with the page // we started with. Two different methods are used to load the // page. With newer browsers, the replace() method is used, so that // the new location will not be added to the history list, and the // Back button on the browser will function normally. With older // browsers, the more familiar href substitution is used instead. function FrameMe() { if (document.images) { top.contentFrame.location.replace(self.location.href); } else { top.contentFrame.location.href = self.location.href; } } // The following code tests whether the current window has two // frames, and if not, runs the frameWriter() function to build // a new frameset and reload the current file inside it. First, // however, it tests whether NN4 is the current browser by // testing for the document.layers object, and, if NN4 is the // current browser, the script tests whether it is printing; // when NN4 prints, it opens the page in a hidden frame whose // innerWidth property is 0. If innerWidth is 0, NN4 is printing, // and so we do nothing. if (!(document.layers && (self.innerWidth == 0))) { if (top.frames.length != 2) { frameWriter() } } // --> </script>
Forcing the keyboard focus into the right-hand frame
Keyboard users tend to find a frame-based site annoying because they usually must click inside a frame before they can move up and down the frame with the arrow keys or PgUp and PgDn. The following brief script in the <HEAD> element of each page solves this problem; it is used only in pages with content, not the navigation frame. The if(document.images) statement causes the function to be empty in any browser that does not support the window.focus object (such as NN2 and IE3 or any other browser that does not support JavaScript 1.1); those browsers will ignore the code instead of popping up an error message. (Note: In Netscape 6, this works only intermittently.)
Most browsers will automatically run this script when loading the page, but IE5 will not run the code unless the <BODY> tag of the page contains the statement onLoad=winFoc(). Because this statement is recognized by all browsers including NN2 and IE3, the script tag in the <HEAD> element cannot use the attribute language=JavaScript 1.1 to prevent the script from running (and generating an error message) in NN2 and IE3. Therefore the if(document.images) statement is used instead.
<script language="JavaScript type="text/javascript"> <!-- function winFoc() { if (document.images) window.focus(); } // --> </script>
Closing a popup window when the opening page is closed
A popup window is usually more annoying than it is worth, but if the web author is polite enough to close the popup automatically when the user wants to go to another page, the popup can serve a useful purpose. This site uses popup windows for site-wide searches and for the large illustration for the essay on the page adamsgrave.html. The search window is available to all JavaScript-enabled browsers, except Opera 3 and 4, which were too buggy to handle the functions required.
With IE, unfortunately, if the browser's advanced options have "browse in a separate process" switched on, there is nothing (including this code) that will make a popup window close when the opening window closes, because, in this case, the opening window has no way of communicating with the popup after it has been opened. For this and other reasons, the search window includes a "close this window" link leading to a self.close function.
The srchOpen() function is used to open the window, and is invoked
when the user clicks on a link in the opening frame. The
Different code is used to open the search window in IE4+ (and NN6), in NN4, and in earlier browser versions. The IE4+ (and NN6) code used on the contentsIE4.html and contentsIE4.html pages appears below:
<script language="JavaScript" type="text/javascript"> <!-- // Start by setting var srchWin=null so IE doesn't complain that // srchWin has no properties if the user closes this frame without // opening the search window (a major headache). var srchWin = null; // The srchOpen() function opens the window itself. Note that IE4+ // supports the little-known top and left attributes for the new // window, corresponding to the better-known ScreenY and ScreenX // attributes supported by NN4. Function srchOpen() { srchWin = window.open('search.html', 'srchName', 'width=310,height=180,scrollBars=yes,resizable=yes,'+ 'top=15,left=12'); } // IE4+ has an annoying bug that somewhat unpredictably // pops up a baffling error message about a Remote Process // Server when a window.close event occurs. The next // two lines turn off error messages while the current // window closes, but leave error messages in their default // state for any document that opens next. this.onerror=doNothing function doNothing() {return true} // The heart of the matter: test whether the search window exists // and whether it has already been closed; if it has not been // closed, close it. Function srchClose() { if ((srchWin != null) && (!srchWin.closed)) { srchWin.close(); } } // --> </script>
The Netscape 4-only code (on the contentsNN4.html page) is much simpler. If the only browser targeted is NN4, then all that needs to be done is add the dependent=yes attribute to the code that opens the popup window (see below); the popup will close by itself when the opening page is unloaded. Somewhat more complicated code is required for NN2/3 and can also be used by IE3; it is found on the contents.html page, where it is accessible to all browser versions earlier than 4, except Opera. All the Netscape (and IE3) code follows:
<script language="JavaScript" type="text/javascript"> <!-- // With NN4, if "dependent=yes" is listed as one of // the attributes of the popup window, the popop will // close by itself when the opener page is closed, // so the following function is all that's needed in // NN4 to close the window that is opened by a link to // the srchOpen() function. Function srchOpen() { srchWin = window.open('search.html', 'srchName', 'dependent=yes,width=310,height=180,scrollBars=yes,'+ 'resizable=yes,screenX=12,screenY=15'); } // The following function is needed only for NN2/3, which // also need "onUnload=srchClose()" in the tag that opens // the window. Function srchClose() { if (srchWin != null) { if (!srchWin.closed) { srchWin.close(); } } } // --> </script>
Note that on the contents.html and homepage.html pages, the link to the search page is written to the screen using JavaScript so that the link appears only in JavaScript-enabled browsers. The link on homepage.html runs the window-opening function from code in the menu frame, not from its own frame, because doing so ensures that the search window will close itself only when a visitor exits the site and the menu frame is closed, not when homepage.html itself is closed and the user goes to another page on the site.
Note also the script that writes the link on the contents.html and homepage.html pages prevents the the link from being written to JavaScript-enabled versions of the Opera browser before version 5. The method of detecting versions 3 and 4 of Opera is especially elaborate because Opera uses different strings to identify itself depending on the subversion of Opera 3 and user settings in version 4.
This is the script (based on browser-sniffer code provided by Mozilla.org with extra refinements for Opera) included in-line in the contents.html and homepage.html pages:
<script language=JavaScript type="text/javascript"> <!-- var agt=navigator.userAgent.toLowerCase();
if ((agt.indexOf("opera/3") != -1) ||
(agt.indexOf("opera 3") != -1) ||
(agt.indexOf("opera/4") != -1) || (agt.indexOf("opera 4") != -1))
{}
else { document.write("<a href='javascript:parent.menuFrame.srchOpen();'>"); document.write("Search</a>"); } // --> </script>
The menus in the navigation frame to the left use DHTML to display and reveal text at the foot of the menu as the mouse pointer passes over items on the menu. Unlike many DHTML menus, they do not rely on absolute positioning, so that the text aligns itself properly in all browsers, and the menus load quickly. The methods used for the menus for Internet Explorer and Netscape 6+ are almost trivially easy, but those used to achieve similar effects in Netscape 4 seem not to be widely known.
The NN4 code uses the NN4-only <ILAYER> tag combined with CSS styles and JavaScript functions. The IE4+ code (and the similar NN6 code) use the <SPAN> tag combined with CSS and JavaScript. The viewer and hider functions are the relevant parts of the code, and most webmasters will be able to work out the details directly from the the source code of the NN4 menu page, the source code of the IE4+ menu page or the source code of the NN6 menu page. The NN6 code uses modifications to the original IE4+ code that were provided by Martin Honnen.
The IE4+ and NN6 menus use the same tags in the <BODY> element but different JavaScript code in the <HEAD>. It would be easy to combine the two menus in one, using an if (document.all) statement to branch to the IE4+ code, but because IE4+ and NN6 render CSS styles differently, the page would have to load one of two external style sheets, one for IE4+, the other for NN6. As this would delay the display of a page that needs to be displayed quickly, it seemed easiest to use separate pages, despite the increased maintenance requirements.
The menus are not entirely text-only: an image appears when the pointer passes over the header at the top of the menu. Note that the image is selected randomly before being loaded in order to avoid the overhead of loading multiple images first and selecting them randomly afterward.