DevEdge Online Archive
This page may be OBSOLETE. Bookmark the NEW DevEdge site.
The Universal HTML Presentation Template:
An Example of Crossware Using JavaScript, Style Sheets, and Cross-Browser Dynamic HTML
(Version 3.0)

Eric Krock
Technology Evangelist


INTRODUCTION

Would you like to put presentation slides on the web the same day you deliver the presentation? Would you like to give a presentation with integrated web technology demos without switching back and forth between the browser and a proprietary page turner? Would you like to get your message out to all potential customers regardless of which browser, platform, or office suite they use? Would you like to let all your customers download, view, edit, reuse, and redistribute a presentation regardless of which platform they use? Netscape's free cross-browser Dynamic HTML presentation template makes this all possible.

The presentations for Netscape's Developer Conference (DevCon) were authored in HTML and viewed using a simple presentation template which was developed using JavaScript, style sheets, and Dynamic HTML. This TechNote explains the techniques used in designing the presentation template. The presentation template itself is available as a ZIP file for free downloading and distribution and includes a read_me.htm file which explains how to use it. The presentation template is an example of crossware, software which is developed using platform-independent technologies like JavaScript and HTML and can be used on all the platforms in use today including Windows 3.1, Windows 95/NT, PowerMac, and UNIX. As a cross-browser Dynamic HTML application, the presentation template is fully functional in both Netscape Navigator 4.0 and Internet Explorer 4.0. It is also backward-compatible with Netscape Navigator 3 and can display presentations with gracefully degraded default HTML formatting in that version of the browser.

Netscape benefited greatly from authoring and distributing the DevCon presentations using this template. Presenters were free to author on the platform of their choice using the HTML editing software of their choice. Because of the seamless cross-platform compatibility of the HTML file format and the JavaScript language, presentations which had been authored on Windows 95, Windows NT, PowerMac, and various UNIX platforms were later displayed on stage using Windows 95 and Sun Solaris UNIX. Because all of the presentations were authored in an open standard format, they could be made available on the World Wide Web to customers on all platforms immediately after DevCon ended. Because the format of the presentations was defined by external style sheet files instead of by hardcoded tags in each HTML page, it was easy to revise the format of all the presentations, even at the last minute, and it was easy to keep a consistent look and feel across all of the presentations. Those presenters who did technical demonstrations of HTML, JavaScript, and Java were able to embed the demos within the presentation pages themselves, eliminating the need to flip back and forth between proprietary page-turner software for slides and the browser for demonstrations. And it has been easy since DevCon for employees throughout Netscape to reuse the presentations on their own machines. The "speaker notes" feature makes it easy for presentation authors to embed hidden explanatory text in the HTML pages to help others who must deliver the same presentation, and the "tutorial mode" feature makes it possible to turn presentations into self-guided online tutorials with minimal additional effort. Since DevCon, the template has been further enhanced to provide full support for Internet Explorer 4.0 and to degrade gracefully on Navigator 3.

Netscape is providing this TechNote and the enhanced version of the DevCon template to make it easy for customers to use the template themselves and to customize it as they wish. This TechNote assumes the reader is familiar with JavaScript, Cascading Style Sheets, level 1 (CSS1), Positioning HTML Elements with Cascading Style Sheets (CSSP), and Netscape's Document Object Model, which makes the formatting and positioning properties of style sheets accessible from JavaScript. (If you are not familiar with these technologies, first go to Netscape's Dynamic HTML Presentations Page and click through Netscape's Visual Tutorials on CSS1, CSSP, and Accessing Style Sheet Properties from JavaScript via the Document Object Model.) If you aren't familiar with the differences between the JavaScript Document Object Model of Navigator 4.0 and of Internet Explorer 4.0, read Danny Goodman's View Source article CSS Positioning -- The Dynamic HTML Neutral Zone.

The body of this document may be browsed and printed with any browser. The demonstrations and the presentation template itself require Navigator 4.x or later or Internet Explorer 4.0 for fully formatted viewing, but they can be viewed as HTML text with default formatting in Navigator 3.x.


A NOTE ABOUT VERSIONS 2.0 AND 3.0

Netscape has twice released enhanced versions of this presentation template and TechNote, Version 2.0 on October 3, 1997, and Version 3.0 on June 5, 1998. All of the information in this TechNote has been revised for Version 3.0 of the presentation template. Version 3.0's only new feature is full support for Internet Explorer 4.0. The major new features of Version 2.0 were the ability to view text of presentations in Navigator 3.x, keyboard navigation (when using Navigator 4.x), a new tutorial mode for making visual tutorials with accompanying explanatory text, the ability to scale presentation font size up or down by any amount, and the alternative frameset documents index2.htm and notes2.htm, which include graphical navigation arrows. For full information about the differences between Version 1.0, Version 2.0, and Version 3.0, see What's New in Version 2.0 and What's New in Version 3.0 in the template's read_me.htm file.


GETTING STARTED

Before reading on, please take a moment to try out the presentation template by using it to view a sample presentation. When viewing the sample presentation:

To familiarize yourself with the template and the way it automatically formats HTML pages, please click these buttons using Netscape Navigator 4.x or Internet Explorer 4.0. These buttons will automatically open new full-screen windows to display the presentation; when you close those windows, this page will still be open.


Alternatively, you can open the demo windows by using these ordinary HTML links. Be sure to full-screen the window and hide the tool bars:

If you want more detailed information about the presentation's features, read the read_me.htm file, which includes full instructions for viewing and authoring presentations.


KEY FEATURES AND FILES

The heart of the presentation template is the JavaScript file style.js (in the presentation template's main directory) which detects the user's display size and scales the HTML text's font size up or down to match it. By scaling the size of the text to match the screen's width in pixels, we ensure that the same amount of screen area is used by the page on any monitor. A "full page of HTML" will look like a "full page" whether it is being viewed on a screen running at 640x480, 800x600, 1600x1200, or some other pixel resolution. This simple trick reliably preserves line and page breaks at different screen resolutions and achieves a visual effect one could call "resolution-independent HTML formatting."

style.js defines global boolean variables called tutorialMode and speakerNotesMode, which determine whether the presentation is being viewed in "tutorial mode" or "speaker notes mode" instead of the default presentation mode. In these two modes, the presentation text is displayed in a smaller font size, leaving extra space at the bottom of the screen. In this space, explanatory tutorial text or speaker notes about the slide are made visible. The tutorial text and speaker notes text are made invisible during normal presentation viewing by hiding the DIV elements which contain them. Conversely, in tutorial mode the DIV element with ID="tutorialsection" is made visible, and in speaker notes mode the DIV element with ID="speakernotessection" is made visible. If you haven't already, compare how the presentation looks in normal mode, speaker notes mode, and tutorial mode.

style.js also defines some other text styles that are used throughout the presentation, such as the red-on-yellow agenda highlighting text style "agendahilite," the right-aligned footnote text style "footnote," and the boldfacing of all PRE elements (to make source code samples more easily visible at a distance).

Currently, the presentation template defines most formatting settings in the JavaScript file style.js. A second style sheet file style.css is provided for the convenience of users who would like to define additional formatting settings using CSS1 syntax. All HTML pages in the sample presentation and the template directories link in both of these files; their settings cascade together. style.js is loaded after style.css, so its settings take priority in the event of a conflict. This enables the JavaScript in style.js to make dynamic modifications at display time to the static settings in style.css.

The JavaScript file slide.js, also in the presentation template's main directory, defines the order of the HTML files in the presentation. In it, the AddSlide function takes one parameter (a filename string), adds that filename to the end of array filename, and increments a global counter last_slide of the number of slides in the presentation. The JavaScript file navbar.js, contained in the presentation template's basefile directory, defines the functions prev_slide, next_slide, and goto_slide, which go to the the previous, next, or user-specified pages respectively.

index.htm is a frameset document for displaying the presentation in front of the audience (in normal mode); it disables scroll bars (with the HTML markup SCROLLING="NO") for the central content frame since presentation authors are expected to size content so that it can be displayed without scrolling. notes.htm is a frameset document for viewing speaker notes and tutorials; it enables scroll bars (default behavior) for the central content frame since lengthy speaker notes may not always fit on a single page without scrolling. To see the HTML markup of these two documents, follow their links and select View | Page Source from the pulldown menu.

Two other frameset documents, index2.htm and notes2.htm, differ from index.htm and notes.htm only in that they provide clickable left-right graphical arrows to page back and page forward.


SETTING ELEMENT STYLES FROM JAVASCRIPT

The Cascading Style Sheets, level 1 (CSS1) specification defines how to set the format of HTML elements using its syntax in style sheets which may be external (in a separate file from the HTML elements) or inline (contained within a <STYLE type="text/css"> element inside the HTML file itself). Netscape Communicator supports the CSS1 specification and Netscape recommends the use of CSS1 syntax style sheets as an industry-standard way of defining the format of an HTML file.

CSS1 settings, while powerful, have one fundamental limitation. CSS1 is designed to be a static file formatting language, not a programming or scripting language, so it is unable to do things like check the current display size and conditionally set font sizes to developer-defined values in response. For this kind of application, a scripting language like JavaScript is required. JavaScript 1.2 makes all CSS1 settings accessible from JavaScript via the Document Object Model (DOM), which exposes these settings as a set of document object properties. For more information about the Document Object Model, see the JavaScript reference manual.

The following sections explain various features of the presentation template as examples of the effects which can be achieved by combining static CSS1 formatting and CSSP positioning with intelligent JavaScript control.

Detecting the Browser Vendor and Version (style.js)

Version 3.0 of the presentation supports Navigator 4.0 and Internet Explorer 4.0, but there are numerous differences between the implementations of JavaScript 1.2 and the Document Object Model in Navigator 4.0 and Internet Explorer 4.0. Moreover, the presentation template provides backward compatibility for Navigator 3.0, which lacks support for Dynamic HTML and the new features of JavaScript 1.2.

To provide support for all three browsers, the presentation template detects the vendor and version number of the user's browser using JavaScript browser-detect code copied from The Ultimate JavaScript Client Sniffer:

// This is a simplified version of the JavaScript Client Sniffer code // found at http://developer.nextscape.com/docs/examples/javascript/browser_type.html function Is () { // convert all characters to lowercase to simplify testing var agt=navigator.userAgent.toLowerCase() // --- BROWSER VERSION --- this.major = parseInt(navigator.appVersion) this.minor = parseFloat(navigator.appVersion) this.nav = ((agt.indexOf('mozilla')!=-1) && ((agt.indexOf('spoofer')==-1) && (agt.indexOf('compatible') == -1))) this.nav2 = (this.nav && (this.major == 2)) this.nav3 = (this.nav && (this.major == 3)) this.nav4 = (this.nav && (this.major == 4)) this.ie = (agt.indexOf("msie") != -1) this.ie3 = (this.ie && (this.major == 2)) this.ie4 = (this.ie && (this.major == 4)) this.opera = (agt.indexOf("opera") != -1) this.nav4up = this.nav && (this.major >= 4) this.ie4up = this.ie && (this.major >= 4) }

Later in the code, the boolean variables defined here (is.nav3, is.nav4up, and is.ie4up) are used to conditionally evaluate the correct JavaScript code for the user's browser. Serial if statements check the boolean variables, and only the code block for the user's browser is evaluated.

Determining the Screen Width in Pixels (style.js)

style.js first checks the current screen width in pixels by getting the width property of the screen object, which exists in both Navigator 4.0's and Internet Explorer 4.0's implementations of JavaScript 1.2:

var screenWidth = screen.width

Setting Font Sizes by Element Name and by Class From JavaScript (style.js)

A series of if clauses then set the HTML element font sizes to the appropriate value for the current view mode and display size. For example, the first two if clauses set the font sizes for viewing on 640x480 and 800x600 screen resolutions:

/* 640x480 is 0.8 times the size of 800x600, so scale down by 20%. */ if (screenWidth < 700) { fontSizeOf = setFontSizes (27, 27, 27, 27, 27, 27, 27, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 10, 14, 17, sizeMultiplier, minFontSize) } /* 12" monitor of 800x600 pixels is the size which we consider "base"; all other sizes are designed to scale so that their content will fit within an 800x600 pixel size area. This is the pixel size used by 12" laptop monitors as well as many overhead display systems. */ else if (screenWidth &lt; 900) { fontSizeOf = setFontSizes (34, 34, 34, 34, 34, 34, 34, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 12, 18, 21, sizeMultiplier, minFontSize) }

The particular font size values for each HTML element in these function calls were selected at 800x600 resolution by a graphic artist for ease of viewing by an audience and then adjusted arithmetically to scale downward and upward for other screen resolutions.

These if clauses call function setFontSizes to set the size of each HTML element:

Here is the code that checks the current browser and then evaluates the appropriate code to set the sizes of HTML elements:

function setFontSizes (h1, h2, h3, h4, h5, h6, titlepage, p, li, ul, ol, dl, dt, dd, blockquote, th, td, pre, tt, small, medium, large,sizeMultiplier, minFontSize) {var fontSizeOf = new constructFontSizeOf (h1, h2, h3, h4, h5, h6, titlepage, p, li, ul, ol, dl, dt, dd, blockquote, th, td, pre, tt, small, medium, large, sizeMultiplier, minFontSize) if (is.nav4up) { document.tags.H1.fontSize = fontSizeOf.h1 document.tags.H2.fontSize = fontSizeOf.h2 document.tags.H3.fontSize = fontSizeOf.h3 document.tags.H4.fontSize = fontSizeOf.h4 document.tags.H5.fontSize = fontSizeOf.h5 document.tags.H6.fontSize = fontSizeOf.h6 document.tags.PRE.fontSize = fontSizeOf.pre document.tags.P.fontSize = fontSizeOf.p /* BUG WORKAROUND: Shouldn't be necessary to set fontSize on UL and OL as well as LI, but setting LI fontSize doesn't work now. Setting on UL and OL is the workaround. */ document.tags.LI.fontSize = fontSizeOf.li document.tags.UL.fontSize = fontSizeOf.ul document.tags.OL.fontSize = fontSizeOf.ol document.tags.DL.fontSize = fontSizeOf.dl document.tags.DT.fontSize = fontSizeOf.dt document.tags.DD.fontSize = fontSizeOf.dd document.tags.BLOCKQUOTE.fontSize = fontSizeOf.blockquote document.tags.TH.fontSize = fontSizeOf.th document.tags.TD.fontSize = fontSizeOf.td document.classes.titlepage.all.fontSize = fontSizeOf.titlepage document.classes.small.all.fontSize = fontSizeOf.small document.classes.medium.all.fontSize = fontSizeOf.medium document.classes.large.all.fontSize = fontSizeOf.large document.classes.footnote.all.fontSize = fontSizeOf.small } else if (is.ie4up) { // document.styleSheets[ieTargetStyleSheetID].addRule ("", "" + ":" + ""); document.styleSheets[ieTargetStyleSheetID].addRule ("H1", "font-size:" + fontSizeOf.h1) document.styleSheets[ieTargetStyleSheetID].addRule ("H2", "font-size:" + fontSizeOf.h2) document.styleSheets[ieTargetStyleSheetID].addRule ("H3", "font-size:" + fontSizeOf.h3) document.styleSheets[ieTargetStyleSheetID].addRule ("H4", "font-size:" + fontSizeOf.h4) document.styleSheets[ieTargetStyleSheetID].addRule ("H5", "font-size:" + fontSizeOf.h5) document.styleSheets[ieTargetStyleSheetID].addRule ("H6", "font-size:" + fontSizeOf.h6) document.styleSheets[ieTargetStyleSheetID].addRule ("PRE", "font-size:" + fontSizeOf.pre) document.styleSheets[ieTargetStyleSheetID].addRule ("P", "font-size:" + fontSizeOf.p) /* BUG WORKAROUND: Shouldn't be necessary to set fontSize on UL and OL as well as LI, but setting LI fontSize doesn't work now. Setting on UL and OL is the workaround. */ document.styleSheets[ieTargetStyleSheetID].addRule ("LI", "font-size:" + fontSizeOf.li) document.styleSheets[ieTargetStyleSheetID].addRule ("UL", "font-size:" + fontSizeOf.ul) document.styleSheets[ieTargetStyleSheetID].addRule ("OL", "font-size:" + fontSizeOf.ol) document.styleSheets[ieTargetStyleSheetID].addRule ("DL", "font-size:" + fontSizeOf.dl) document.styleSheets[ieTargetStyleSheetID].addRule ("DT", "font-size:" + fontSizeOf.dt) document.styleSheets[ieTargetStyleSheetID].addRule ("DD", "font-size:" + fontSizeOf.dd) document.styleSheets[ieTargetStyleSheetID].addRule ("BLOCKQUOTE", "font-size:" + fontSizeOf.blockquote) document.styleSheets[ieTargetStyleSheetID].addRule ("TH", "font-size:" + fontSizeOf.th) document.styleSheets[ieTargetStyleSheetID].addRule ("TD", "font-size:" + fontSizeOf.td) document.styleSheets[ieTargetStyleSheetID].addRule (".titlepage", "font-size:" + fontSizeOf.titlepage) document.styleSheets[ieTargetStyleSheetID].addRule (".small", "font-size:" + fontSizeOf.small) document.styleSheets[ieTargetStyleSheetID].addRule (".medium", "font-size:" + fontSizeOf.medium) document.styleSheets[ieTargetStyleSheetID].addRule (".large", "font-size:" + fontSizeOf.large) document.styleSheets[ieTargetStyleSheetID].addRule (".footnote", "font-size:" + fontSizeOf.small) } return fontSizeOf }

The same code segment sets the font size for all elements of CLASS "small," "medium," or "large" to the values passed in as parameters small, medium, and large. In Navigator 4.0 JavaScript, HTML elements can be selected by class from JavaScript by using the classes property of the document object, followed by the name of the class and a qualifier (here all, indicating that all elements of that class should be selected). Finally, the name of the property to set (in this case fontSize) and its value are specified. In Internet Explorer 4.0 JavaScript, the addRule method is again used, this time with the class selectors ".small", ".medium", and ".large",.

Storing Element Font Size Settings for Later Use (style.js)

The element styles for the current screen size have been now been set for the HTML page, but they also need to be stored in a data structure so that page-specific style sheets can reference them later. The first line of function setFontSizes calls constructor function constructFontSizeOf to initialize an object to store this data. This object is the return value of function setFontSizes, and global variable fontSizeOf is set to this object at the top level. For an example of a page-specific style sheet that uses this stored data, see Page-Specific Style Sheets.

Scaling the Text in Speaker Notes Mode and Tutorial Mode (style.js)

In addition to scaling the standard font sizes to match different screen resolutions, the template must adjust the standard font sizes downward to provide a slightly smaller font size in tutorial mode and an even smaller font size in speaker notes mode. In these modes, more text is generally used per page than in standard presentation mode, and the content is being read by an single individual in front of a display rather than by a presenter on screen in front of a large audience. The smaller font sizes are used to reduce the need to scroll down to read text on each page.

To scale the standard font sizes downward, style.js first defines global variables which define whether the presentation is running in speaker notes mode or tutorial mode. There are three versions of style.js for presentation mode, speaker notes mode, and tutorial mode. Each version sets the global variables appropriately. Here is the source code from the version of style.js for presentation mode:

//Global variables speakerNotesMode and tutorialMode determines //whether we are in: // // * speaker notes display mode (speaker mode text visible, // all text in smaller fonts so speaker notes fit on screen) // * tutorial mode (tutorial mode text visible, text in slightly // larger fonts for online viewing) // * normal mode (speaker mode text invisible because color is same // as backgroundcolor, all text in large fonts appropriate for // overhead display). var speakerNotesMode = false var tutorialMode = false

Next, a scaling ratio sizeMultiplier is defined and set to 1.0 by default. This variable is set to 0.55 in speaker notes mode and 0.79 in tutorial mode to produce text which is 55% and 79% of normal size, respectively:

// Adjust font sizes downward in speakerNotes and tutorial modes. var sizeMultiplier = 1.0 // default if (tutorialMode) sizeMultiplier = 0.79 // online viewing if (speakerNotesMode) sizeMultiplier = 0.55 // speaker preparation with notes var minFontSize = 12 // smallest ever displayed

To make sure that font sizes which are small to begin with are not scaled downward to values which render the text unreadable, an additional variable minFontSize is defined; no font size value is ever scaled downward below this value. minFontSize is set to 12 points by default.

The font size scaling calculation actually takes place in function calcSize, which is called by function constructFontSizeOf to adjust the font size of each element to match the current mode. The return value is a string including the unit indicator "pt", for "points." This string is used by the statements in function setFontSizes to set each element's font size.

// Calculates font size to be used for element, which is // the maximum of specified*sizeMultiplier and minAllowed. // Returns as string for storage in data structure fontSizeOf. function calcSize (specified, sizeMult, minOK) { return ( Math.max (Math.round(specified*sizeMult), minOK) + "pt" ) }

Hiding the Speaker Notes Text and Tutorial Text by Setting an Element's Visibility with CSSP (style.css, s_agenda.htm)

Presentation pages usually include normal text (shown at all times), speaker notes text (which are notes for the use of the presenter while rehearsing the presentation), and tutorial text (displayed when the presentation is being used online as a self-guided tutorial). The speaker notes text and tutorial text must be hidden when the presentation is being displayed in front of an audience. For an example of the use of speaker notes text, compare page 3 (the "Agenda" page) of the sample presentation when viewed in normal mode and speaker notes mode.

HTML 3.2 does not include support for true conditional text, but it can be simulated in Dynamic HTML through the ability to hide and show HTML elements and their contents. The presentation template demonstrates this ability.

In the HTML files of the presentation's pages, speaker notes text is at the end of the BODY (just before the </BODY> tag) inside a <DIV ID="speakernotessection"> element. The DIV element is used in HTML to define sections within an HTML document and can contain any other HTML elements inside it. By setting the ID attribute of this DIV element to "speakernotessection", we give it a unique identifier (name) which can be used to access that element and set its properties. We also indicate that all enclosed elements are to be considered speaker notes text.

In the version of style.css for presentation mode, we specify that any elements with ID="speakernotessection" or ID="tutorialsection" are to be initially hidden by setting their visibility properties to hidden; this ensures that the elements (and all of their contents) will be initially hidden so that they do not appear on screen during normal presentation viewing:

#speakernotessection {position:absolute; visibility:hidden;} #tutorialsection {position:relative; visibility:hidden;}

In presentation mode, we have no need to explicitly control the positioning of the DIV elements on the screen; we only need to hide these elements, not reposition them. Since the speaker notes text and tutorial text will be hidden, we allow them to be shown on the screen where they would normally be placed by the browser's default positioning rules. To do this, we specify that they are positioned HTML elements by setting each element's position property (one to absolute, the other to relative); this is necessary to expose the elements for positioning and hiding within the Navigator 4.0 Document Object Model. Although we give the elements unique identifiers and declare them to be positioned (which together exposes the elements for positioning and hiding within the Navigator 4.0 Document Object Model), we do not specify what the elements' actual positions are. Therefore, the elements are displayed at their default positions within the default layout of the HTML page.

An important point: Any HTML element that is named and positioned (either by CSS Positioning or by the LAYER tag) becomes a Positioned HTML Element Object in Navigator 4.0 JavaScript. The positioning and visibility properties of this object can then be read and set dynamically from JavaScript. To access the object, we use the JavaScript syntax document.identifier , where identifier is the element's identifier, specified by the value of its ID attribute. In Internet Explorer 4.0 JavaScript, such elements can be accessed through use of the document.all collection with the syntax document.all.identifier .

Displaying the Tutorial Text by Setting an Element's Visibility with CSSP (style.css)

In the version of style.css for tutorial mode, we set the visibility property of the element with ID="tutorialsection" to visible without altering its position on the screen:

#speakernotessection {position:relative; visibility:hidden;} #tutorialsection {position:relative; visibility:visible;}

Since we wish to display the now-visible tutorial text in its default position (directly below the always-visible presentation text), there is no need to reposition the tutorial text element, so we specify relative positioning with no offset.

Getting the JavaScript Objects for HTML Elements on Navigator 4.0 and Internet Explorer 4.0 (style.js)

In subsequent sections, this TechNote explains how the presentation template uses JavaScript to hide, show, and move HTML elements. Before you can hide, show, or move an HTML element, you must get the JavaScript object which represents that HTML element. Because Navigator 4.O and Internet Explorer 4.0 have a different Document Object Model, you must use different JavaScript code on Navigator 4.0 and Internet Explorer 4.0 to get the HTML element's JavaScript object. If you aren't familiar with the differences between the JavaScript Document Object Model of Navigator 4.0 and of Internet Explorer 4.0, read Danny Goodman's View Source article CSS Positioning -- The Dynamic HTML Neutral Zone.

To be able to get an HTML element's JavaScript object on both browsers, you must declare the element to be positioned and give it a unique name. (For full details, see the related TechNote about Setting CSSP Properties From JavaScript on Both Browsers.) Thereafter, you can use the function getElt(), below (which is included in the TechNote Setting CSSP Properties From JavaScript on Both Browsers), to retrieve the JavaScript object for an HTML element by using its name:

// This function is excerpted from the cross-browser JavaScript API for setting CSSP properties // which can be found at http://developer.netscape.com/docs/technote/dynhtml/csspapi/csspapi.html /* CALLING SYNTAX: each Name is a string which is an element's ID attribute value or a LAYER tag's NAME attribute value. getElt (topLevelElementName, childElementName, grandchildElementName, targetElementName) Example of getting a top-level element: var fooElement = getElt ("foo") Example of getting a nested element: var fooElement = getElt ("bar", "baz", "foo") ... where baz is foo's containing parent, and bar is a top-level element which is baz's containing parent. */ function getElt () { if (is.nav4up) { var currentLayer = document.layers[getElt.arguments[0]]; for (var i=1; i<getElt.arguments.length && currentLayer; i++) { currentLayer = currentLayer.document.layers[getElt.arguments[i]]; } return currentLayer; } else if (is.ie4up) { var elt = eval('document.all.' + getElt.arguments[getElt.arguments.length-1]); return(elt); } }

To get a top-level HTML element's JavaScript object, you pass function getElt() a string which is the HTML element's ID attribute value. getElt() returns the JavaScript object for that element. For example, to get the top-level tutorial text element, you evaluate getElt("tutorialsection"). To get the top-level speaker notes text element, you evaluate getElt("speakernotessection").

Function getElt() is part of the freely downloadable cross-browser API for setting CSSP properties from JavaScript on both browsers, which is contained within the TechNote about Setting CSSP Properties From JavaScript on Both Browsers.

Setting the CSSP Properties of HTML Element Objects (style.js)

Once you have gotten the JavaScript object for an HTML element, you can set the properties of that JavaScript object. Again, because of the differences between the Navigator 4.0 and Internet Explorer 4.0 Document Object Model, some of the property names differ, so you must use different JavaScript code to set a given property on Navigator 4.0 and Internet Explorer 4.0. When running in speaker notes mode, the presentation template needs to move and then show the HTML element that contains the speaker notes text. (This element is initially hidden.) To do that, the presentation template uses functions from the cross-browser Dynamic HTML API contained in the TechNote about Setting CSSP Properties From JavaScript on Both Browsers.

// These functions are excerpted from the cross-browser JavaScript API for setting CSSP properties // which can be found at http://developer.netscape.com/docs/technote/dynhtml/csspapi/csspapi.html /* value must be "visible", "hidden", or "inherit". These values work on both Navigator 4.0 and Internet Explorer 4.0 for setting visibility. */ function setEltVisibility (elt, value) { if (is.nav4up) elt.visibility = value; else if (is.ie4up) elt.style.visibility = value; } /* Move elt to pixel location x,y within its coordinate system, which is the window content area for top-level elements or the parent element's coordinates for nested elements which have an absolutely positioned parent. */ function moveEltTo (elt, x, y) { if (is.nav4up) elt.moveTo(x, y); else if (is.ie4up) { elt.style.pixelLeft = x; elt.style.pixelTop&nbsp; = y; } } /* Returns left edge of elt in pixels. */ function getEltLeft (elt) { if (is.nav4up) return (elt.left); else if (is.ie4up) return (elt.style.pixelLeft); } /* Sets top edge of elt in pixels. */ function getEltTop (elt) { if (is.nav4u return (elt.top); else if (is.ie4up) return (elt.style.pixelTop); }

Positioning the Speaker Notes Text by Setting an Element's Position From JavaScript (style.js, style.css, s_agenda.htm)

When the presentation is being viewed in speaker notes mode, we need to display the hidden speaker notes text and reposition it on the page. In the HTML pages, the presentation text is at the top of the page, the tutorial text is below it, and the speaker notes text is at the bottom. As a result, if we hide the tutorial text and display the speaker notes text in their default positions, there will be a large blank space on the screen (the hidden tutorial text, which is not displayed but, in compliance with the CSSP specification, still takes up layout space) between the presentation text and the speaker notes text.

To solve this problem, we reposition the speaker notes text upward on the screen to the default position of the tutorial text, thus placing the speaker notes text on top of the (hidden) tutorial text. style.js defines a function moveSpeakerNotes which checks four conditions and (if all four conditions are true) executes two statements:

// onLoad method function moveSpeakerNotes () { var speakerElt = getElt("speakernotessection") if (speakerNotesMode && !tutorialMode && speakerElt) { var tutorialElt = getElt("tutorialsection") if (tutorialElt) { /* on Nav4, we explicitly move the speakerElt on top of hidden tutorialElt */ if (is.nav4up) moveEltTo (speakerElt, getEltLeft(tutorialElt), getEltTop(tutorialElt)); /* on IE4, the needed JavaScript properties aren't initialized, so we set display="none" and let reflow bury tutorialElt. */ if (is.ie4up) tutorialElt.style.display = "none"; } setEltVisibility (speakerElt, "visible"); } }

This source code can be explained as by the following if-then sequence.

If:

then:

In writing the moveSpeakerNotes() function, we had to work around a quirk of Internet Explorer 4.0's style properties for HTML element objects. On Navigator 4.0, when an HTML element has been positioned by static CSS markup, the CSS positioning properties of that element's JavaScript object are automatically set to the values specified in the CSS markup. However, on Internet Explorer 4.0, the corresponding properties are in many cases undefined until they have been explicitly set from JavaScript. As a result, the approach we used on Navigator 4.0 (moving the speaker notes element to the position of the tutorial element) cannot be used, as the tutorial element has been positioned with CSS markup, so that element's JavaScript positioning properties cannot be read on Internet Explorer 4.0 from JavaScript after the document loads. As a workaround, on Internet Explorer 4.0 we instead set the tutorialElt.style.display property (in other words, the display property of the style object of the tutorial element) to "none". This causes the tutorial element to disappear from the page layout completely in Internet Explorer 4.0, achieving the same visual effect as on Navigator 4.0 by different means. This approach (achieving the same visual effect by two different means) is the best way to work around the differences between JavaScript and the Document Object Model on Navigator 4.0 and on Internet Explorer 4.0.

style.js defines function moveSpeakerNotes() but does not call it immediately because when style.js is being evaluated, the HTML file has not finished loading, so the JavaScript object for the "speakernotessection" element does not yet exist. We need to wait until the HTML file has finished loading to call this function. To do that, style.js makes function moveSpeakerNotes() the onLoad event handler for the document's frame. On Navigator 4.0, we do this with the statement self.onload = moveSpeakerNotes;. On Internet Explorer 4.0, we do the same thing with the statement top.frames["slide"].window.onload = moveSpeakerNotes;. Here is the source code:

if (speakerNotesMode) {
  if (is.nav4up) {
     document.contextual(document.ids.speakernotessection, document.tags.H1).textDecoration = "underline"
     document.contextual(document.ids.speakernotessection, document.tags.H1).marginTop = "1em"
     self.onload = moveSpeakerNotes;
  }
  else if (is.ie4up) {
     document.styleSheets[ieTargetStyleSheetID].addRule ("#speakernotessection H1", "text-decoration:underline");
     document.styleSheets[ieTargetStyleSheetID].addRule ("#speakernotessection H1", "margin-top:1em");
     top.frames["slide"].window.onload = moveSpeakerNotes;
  }
}

If we are in speaker notes mode, when the HTML file finishes loading, the onLoad event occurs, the function is called, and the HTML element with the speaker notes is moved upward on the page and made visible.

Formatting the Speaker Notes Text by Contextual Selection From JavaScript (style.js, s_agenda.htm)

style.js uses contextual selection to specify that all H1 elements that have an ancestor with ID speakernotessection should be underlined and displayed with a top margin of 1 em space:

if (speakerNotesMode) {
   if (is.nav4up) {
      document.contextual(document.ids.speakernotessection, document.tags.H1).textDecoration = "underline"
      document.contextual(document.ids.speakernotessection, document.tags.H1).marginTop = "1em"
      self.onload = moveSpeakerNotes;
   
   }
   else if (is.ie4up) {
      document.styleSheets[ieTargetStyleSheetID].addRule ("#speakernotessection H1", "text-decoration:underline");
      document.styleSheets[ieTargetStyleSheetID].addRule ("#speakernotessection H1", "margin-top:1em");
      top.frames["slide"].window.onload = moveSpeakerNotes;
   }
}

Contextual selection is a powerful technique which makes it possible for an HTML element's format to vary depending not only on its class, name, or ID, but also on its position within the document structure. In Navigator 4.0, the contextual method of the document object takes as arguments a list of selectors; only elements which match that list of selectors are formatted by the subsequent declaration. On Internet Explorer 4.0, we use the addRule method to achieve the same effect.

Linking in External Style Sheet Files (s_color.htm)

All of the sample HTML pages (in the main presentation directory) and the template HTML pages (in the template and blanktmp subdirectories) link in the external style sheet files style.js (which, strictly speaking, is a JavaScript script that sets element styles using the Document Object Model) and style.css using this HTML markup:

<!-- * Link to import external CSS format style sheet.&nbsp; * --> <LINK REL=STYLESHEET TYPE="text/css" HREF="http://web.archive.org/web/20040928081105/http://developer.netscape.com/docs/technote/javascript/prestemp/style.css"> <!-- * Link to import external JavaScript Script that sets style properties. --> <SCRIPT LANGUAGE="JavaScript1.2" SRC="http://web.archive.org/web/20040928081105js_/http://developer.netscape.com/docs/technote/javascript/prestemp/style.js">

In general, any style settings that may be reused and shared by multiple pages should be placed in an external style sheet file rather than within the HTML file. This approach achieves clean separation of formatting information and content, saves disk space on the server and download time for the user, and enables efficient long-term maintenance of style information in a single location.

Page-Specific Style Sheets (s_color.htm)

Some pages need to use font styles which differ from the presentation defaults. For example, sample HTML file s_color.htm uses a different background color (yellow), different text colors for H2 and H3 elements (red and blue), and different font sizes for P, H2, and H3 elements (medium). Such pages use their own internal styles sheets, defined inside <STYLE> and <SCRIPT> elements within the HTML file itself.

s_color.htm uses this inline CSS1 style sheet to set the background color and the text color for H2 and H3 elements:

<STYLE TYPE="text/css"> BODY { background: yellow; } H2 { color: red } H3 { color: blue } </STYLE>

Next, this inline script sets the fontSize property for P, H2, and H3 elements to property medium of the fontSizeOf object defined earlier in style.js. Since these style settings appear later in the HTML file than the links to the style.css and style.js files, they take precedence where the rules conflict and override the presentation's default settings.

<SCRIPT LANGUAGE="JavaScript1.2"> <!-- if (is.nav4up) { /* use smaller font size than default set in style.jss */ tags.H2.fontSize = fontSizeOf.medium tags.H3.fontSize = fontSizeOf.medium tags.H4.fontSize = fontSizeOf.medium } else if (is.ie4up) { document.styleSheets[ieTargetStyleSheetID].addRule ("H2", "font-size:" + fontSizeOf.medium) document.styleSheets[ieTargetStyleSheetID].addRule ("H3", "font-size:" + fontSizeOf.medium) document.styleSheets[ieTargetStyleSheetID].addRule ("H4", "font-size:" + fontSizeOf.medium) } //--></SCRIPT>

Cascading Multiple Style Sheets to Format a Single HTML Page (s_color.htm)

s_color.htm demonstrates how settings defined in multiple style sheets can cascade together to control the format of a single HTML page according to the priority rules defined in the Cascading Style Sheets, level 1 specification. As explained in the previous section, Page-Specific Style Sheets, a total of four style sheets (two external and two inline) cascade together to determine the format of the HTML page.

Where rules of the same specificity defined in different style sheets for the same element and property conflict, the rule in the style sheet that appears later in the HTML file takes precedence. For example, the page's rule setting the size of H2 elements to medium overrides the style.js rule setting their size because the page's style sheet appears in s_color.htm later than the link to style.js. For more information about the cascading rules governing conflict resolution between different rules, see the Cascading Style Sheets, level 1 specification. Generally speaking, declarations for more specific groups of elements override declarations for more general groups of elements (for example, rules for the unique element with a particular ID override rules for elements of a given class, and rules for elements of a given class override rules for all elements of a given tag name), and declarations which appear later override declarations which appear earlier.


HANDLING KEYBOARD EVENTS (slide.js, basefile/navbar.js)

Navigator 4.0 and Internet Explorer 4.0 also have differences in their APIs for intercepting and handling events. For full details, read Danny Goodman's article JavaScript Apostle: Dueling Event Models -- A Cross-Platform Look in View Source. The following differences are relevant to the presentation template application:

Once again, our JavaScript code checks the current browser and then evaluates the appropriate JavaScript code. Look at the source code of function handleKeys() below to see how.

Getting the Character Code of the Key Which Was Pressed (slide.js, basefile/navbar.js)

Here is the event handler function that is called on both Navigator 4.0 and Internet Explorer 4.0:

// KEYBOARD CONTROL IN Naviator 4.0

// support SPACE key codes (*not* RETURN because of Goto field!)
var nextKeys = new String("nN ")
var prevKeys = new String("pP")

function handleKeys(e) {
     var keyChar;
     if (is.nav4up) keyChar = String.fromCharCode(e.which);
     else if (is.ie4up) keyChar = String.fromCharCode(window.event.keyCode);
     if (prevKeys.indexOf(keyChar) != -1)
     {  prev_slide(); return false  }
     else if(nextKeys.indexOf(keyChar) != -1)
     {  next_slide(); return false  }
     else return true;
}

On Navigator 4.0, the event object is automatically passed as the first argument (argument "e") to the event handler function handleKeys(e). The which property of the event object is the character code of the key which was pressed, so the code String.fromCharCode(e.which); is used to retrieve the character code and convert it to a string for processing.

On Internet Explorer 4.0, the function's argument e is undefined and ignored. Instead, the event object is a property of the window object, so the code String.fromCharCode(window.event.keyCode); is used to retrieve the character code and convert it to a string for processing.

Capturing the Event (slide.js, basefile/navbar.js)

The following code is used to register function handleKeys() as the event handler for the keypress event:

if (parseInt(navigator.appVersion) > 3) { if (is.nav4up) document.captureEvents(Event.KEYPRESS); document.onkeypress = handleKeys; } // end of Nav4+ only if

On Navigator 4.0, we register our intention to capture and handle the keypress event by evaluating document.captureEvents(Event.KEYPRESS);. Then, on both browsers, we make function handleKeys() the event handler for the keypress event by evaluating document.onkeypress = handleKeys;. Because Internet Explorer 4.0 doesn't support mixed-case event handler names in JavaScript (such as onKeyPress), we have to use the all-lowercase event handler name onkeypress.


INDEPENDENCE OF CONTENT, FORMAT, AND PRESENTATION FRAMESET

Because the presentation's content (defined by the HTML pages), format (defined by style.js and style.css), and page-turner frameset (defined by index.htm and notes.htm) are all independent of each other, it is easy to change one without disturbing the others. By editing the HTML pages, you can display different content in the same format and within the same frameset. By editing style.js and style.css, you can change the presentation's format but display the same content within the same frameset. Or, by changing index.htm and notes.htm (and the HTML pages basefile/prev.htm and basefile/next.htm which they link to) you can provide a different frameset to display the same content in the same format.

As an example, an alternative frameset is provided by the documents index2.htm and notes2.htm. This frameset features graphical arrows which can be clicked to page forward or backward. In the same way, developers can create other frameset documents to implement the user interface of their choice.


SUPPORTING MULTIPLE BROWSER VERSIONS

While taking full advantage of the power of Dynamic HTML in Navigator 4.x, it is best to ensure that pages and applications are also usable with earlier versions of the browser whenever possible, as earlier versions remain in use even after the newer version is released. Versions 2.0 and later of the presentation template also run without error under Navigator 3.x so that the unformatted text of presentations is still viewable in older versions of the browser. (The text cannot be shown formatted in Navigator 3.x because Navigator 3.x does not support Cascading Style Sheets, and it cannot be viewed at all in Navigator 2.x because Navigator 2.x does not support the SRC attribute of the SCRIPT tag.)

To enable the viewing of presentations in Navigator 3.x, two technical changes were nececessary between Version 1.0 and Version 2.0 of the presentation template: The name of the external JavaScript file was changed from style.jss to style.js, and the Navigator 4.x-specific JavaScript statements were enclosed in an if (parseInt(navigator.appVersion) > 3) { ... } clause.

The name of the external JavaScript file had to be changed from style.jss to style.js because Navigator 3.x would display the content of the file style.jss in the center frame rather than the content of the HTML file. Changing the name of the linked JavaScript file eliminated this problem. To preseve backward compatibility with presentations authored using Version 1.0 of the template, the obsolete file style.jss is retained in the presentation directory.

When running on Netscape Navigator 4.x, the presentation template takes full advantage of JavaScript 1.2's ability to access CSS1 and CSSP properties and intercept keyboard events. JavaScript 1.1 in Navigator 3.x does not support these newer JavaScript features, so code that attempts to access CSS1 and CSSP related JavaScript objects will generate JavaScript errors in Navigator 3.x. The solution to this problem is to enclose JavaScript 1.2-specific statements and function calls in an if (parseInt(navigator.appVersion) > 3) { ... } clause. As a result, these statements are skipped when the file is loaded by Navigator 3.x and processed by the JavaScript 1.1 interpreter, and the application runs without errors under Navigator 3.x.


SUPPORTING MULTIPLE PLATFORMS

Since the presentation template is implemented using JavaScript and HTML -- technologies that are platform-independent -- the ability to support multiple platforms is a benefit that comes almost completely for free. The presentation template was used unchanged at DevCon to author presentations on Windows 95, Windows NT, PowerMac, and various UNIX platforms. On stage, the presentations that had been authored on this variety of platforms were displayed using Windows 95 and Sun Solaris UNIX machines.

To ensure that any presentation authored on any platform can be viewed unchanged on any other platform, only minimal care need be taken to account for platform differences in file naming conventions. Windows 3.1 machines use 8.3 format filenames (eight character filenames followed by a three character extension), so all of the presentation template's files use filenames in 8.3 format. Likewise, when specifying pathname strings in JavaScript (for example, in the style.js file), the forward slash character is used; when this character occurs in a JavaScript pathname string, JavaScript automatically maps it to the appropriate platform-dependent character (backslash on the various Windows platforms, forward slash elsewhere).


REFERENCES

Please refer to the following resources for further information:

TN-JSCR-02-9707

For the latest technical information on DevEdge Archive products, go to: http://developer.netscape.com

For more Internet development resources, try Netscape TechSearch.


Copyright © 1999 Netscape Communications Corporation.
This site powered by: Netscape Enterprise Server and Netscape Compass Server.