DHTMLLib

The CSS-P Cross-Browser Library
Version .90

Last Updated: August 2, 1997

Everything you need to know to use DHTMLLib - The CSS-P Cross-Browser Library. This file contains guidelines and instructions on how to use the Cross-Browser CSS-P Library. This file is a first draft and will be updated over the next few weeks.

This library cannot be redistributed in any way without prior permission from Scott Isaacs. When used, the copyright notice and restrictions must be left in the library file.

This core library free is free to use as long as you comply with the terms outlined in the source code. You can also register a web-site for $50. Registered sites receive

  1. Notifications of new library versions before we release to the web.
  2. At your request, have your web-site included registered supporters page.
  3. An advanced library for use on your web-site that simplifies moving elements and well as choreographing move sequences (move one element, then move another), and helps add cool swipe effects to your documents.

Please send any registrations to:

Scott Isaacs
PO Box 1652
Issaquah, WA 98027

If you have any questions about the library or registration, please send them to DHTMLLib@SiteExperts.com.

In all cases, we very much want feedback. If you design pages with this library, please e-mail us the URL so we may see how this library is being used.

Using the Library

Step 1: Hooking up this Library

Unless prior arrangements are made with www.SiteExperts.com (send mail to scotti@SiteExperts.com), you are free to use the DHTMLLib library on your web-site as long as it is embedded on your page as following.

Place the library on a server with the name "DHTMLLib.js" and reference it as an external script. Change the SRC below to point to the file on your hard drive and add this in the head of your document.

<SCRIPT LANGUAGE="JavaScript" SRC="DHTMLLib.js">
  // DHTMLLib.js - copyright 1997 by Scott Isaacs - www.insideDHTML.com
  // If desired, insert code here to execute on browsers that do not support the SRC attribute.
</SCRIPT>

Custom Onload Event Handlers

This script relies on calling a function in the onload event to initialize itself. Therefore, if you write your own onload event handler, you need to make sure to call the setup() function as demonstrated below:

<SCRIPT LANGUAGE="JavaScript">
  // Optional Custom Onload Event
  function doLoad() {
    setup();  // Call the library setup routine first
    // Write your onload code here
  }
  window.onload = doLoad;
</SCRIPT>

Step 2: Authoring your HTML

Both Netscape and Microsoft support CSS Positioning to different degrees on different elements. Be sure to read the CSS-P specification at the W3C web-site (we will put a tutorial on-line in the coming weeks). We have found the following combination is the most reliable and consistent across browsers:

Examples:

1. To position an image:

<DIV ID=pos1 STYLE="position: absolute; top: 10px; left: 10px">
  <IMG SRC="cool.gif">
</DIV>

Step 3: Writing your Script

Guidelines:

The library is designed to script any positioned element in your document. To script the element it must have a document wide unique identifier:

wrong way - sharing IDs:

<DIV ID=pos STYLE="position: absolute; top: 10px; left: 10px">
</DIV>
<SPAN ID=pos STYLE="position: relative; top: 10px; left: 10px">
</SPAN>

right way - unique IDs:

<DIV ID=dpos1 STYLE="position: absolute; top: 10px; left: 10px">
</DIV>
<SPAN ID=spos1 STYLE="position: relative; top: 10px; left: 10px">
</SPAN>

Only use ID's on the positioned elements, and name on the other elements. Netscape and Microsoft both support ID on all positioned elements.

Object Model Reference

Element Collections

Internet Explorer 4.0 exposes an all collection that represents every HTML element in the document (<HEAD>, <BODY>, <H1>, etc.). This library exposes a similar all collection in Netscape for the positioned elements and images. However, this collection is simulated and contains much fewer elements than exposed by IE 4.

For this reason, when writing code against this library, you should never reference an ordinal position in a collection.

wrong way - use an ordinal index:

document.all[0]

right way - use the ID:

document.all["pos"]

In addition, the library automatically flattens the hierarchy Netscape creates when nesting elements in positioned documents.For example:

<IMG NAME="img1" SRC="img1.gif">
<DIV ID="pos1" STYLE="position: absolute; top: 10; left: 10">
  <IMG NAME="img2" SRC="img2.gif">
</DIV>

Netscape 4.0 creates the following collections for the above document:

document.images : 1 element, img1
document.layers : 1 element, pos1
document.layers[0].document.images : 1 element, img2

This library exposes the above document as the following collections:

document.images : 2 elements, img1 and img2 (IE4 automatically exposes this)
document.all : 3 elements, pos1, img1, and img2(IE4 automatically exposes this and all other elements)

To change the src of the images:

document.images.img1.src = "newimage.gif";
document.images.img2.src = "newimage2.gif";
// or
document.all.img1.src = "newimage.gif"

What is Scriptable?

The following elements are fully scriptable and exposed as following using this library:

collection contains
document.all All positioned elements and images
document.images All images
document.forms All forms
document.applets All applets
document.anchors All anchors
document.links All links

When scripting images, forms, applets, anchors, and links you are limited to Netscape's object model. While IE4 exposes every attribute and all the events on every element, Netscape does not.

Programming Positioned Elements:

All positioned elements in the all collection expose the following propertier, methods, and events:

Properties

All properties are read-only. Values can be assigned to many of these properties, but they will not be reflected by Netscape. Instead, set* methods are also exposed for manipulating these values.

id Returns the specified id for the element.
offsetTop Returns the calculated top position relative to its coordinate system in pixels. NOTE: This is estimated in Netscape and is a few pixels off from IE4's value.
offsetLeft Returns the calculated left position relative to its coordinate system in pixels. NOTE: This is estimated in Netscape and is a few pixels off from IE4's value.
offsetWidth Returns the calculated width for rectangular elements in pixels. NOTE: This is estimated in Netscape and is only accurate if no clip is specified.
offsetHeight Returns the calculated height for rectangular elements in pixels. NOTE: This is estimated in Netscape and is only accurate if no clip is specified.
style.zIndex Returns the z-index for the element.
style.pixelLeft Returns the specified CSS left position for the element in pixels.
style.pixelTop Returns the specified CSS top position for the element in pixels.
style.pixelWidth Returns the specified CSS width for the element in pixels.
style.pixelHeight Returns the specified CSS height for the element in pixels.
style.backgroundColor Returns the specified CSS background color for the element.
style.backgroundImage Returns the specified CSS background image for the element. This property is returned as a string in the format of "url(backgroundImagePath)".
style.visibility Returns the CSS visibility property.

Events

The following events are available on the following objects. Read the next section, Events to learn more about using the events.

Events on absolute positioned elements:

onmousedown, onmousemove, onmouseup, onmouseover, onmouseout, 
onkeydown, onkeypress, onkeyup

Events on the document:

onmousedown, onmousemove, onmouseup, 
onkeydown, onkeypress, onkeyup, 
onclick, ondblclick

Window Methods

These methods are used to change the values of the properties and contents of the positioned element. The first argument is always the positioned element to manipulate.

setContent(el, content) Replaces the content of the element with the specified content string. Use only on absolute positioned elements.
setZIndex(el, zindex) Change the positioned elements ZIndex. ZIndex defines whether the element is displayed is above or below other positioned elements. Higher values are on top of lower values.
setPosition(el, [top [, left]]) Sets a new top-left position for the element in pixels. The parameters are optional. For example:
setPosition(document.all.myEl, 25) // Sets a new top position
setPosition(document.all.myEl, null, 50) // Sets just a new left position
setVisibility(el, visible) Sets the visibility of the element. Valid values are: visible, hidden, and inherit.
setColor(el,color) Sets the background color of the element.

Event Model

This library adds minimal "event bubbling" in Netscape. Event Bubbling is a feature where the events first occur on a source element in the document, then each parent element in the document also receives the event. For example:

<HTML>
  <SCRIPT SRC="DHTMLLib.js">
  </SCRIPT>
  <SCRIPT>
    function demo() {
      setup();
      document.onmousedown = new Function("alert('doc mousedown')")
      document.all.pos1.onmousedown = new Function("alert('pos1 mousedown')")
    }
    window.onload = demo;
  </SCRIPT>
  <BODY>
    <DIV ID=pos1 STYLE="position: absolute; top: 20; left: 20">
      <A HREF="#" onmousedown="alert('anchor mousedown')">Test Me</A>
    </DIV>
  </BODY>
</HTML>

Clicking on the anchor above fires the onmousedown event to the anchor, the positioned element pos1, and the document so you will see 3 alerts. (note: IE4 also fires it to the BODY and HTML element).

While IE4 fires bubbles all events through every element, due to limitations in Netscape, the library is only capable of firing events through elements Netscape supports events on. For example, if the onclick event is trapped on the anchor, you should only script the anchor's onclick event or the document's onclick event. The DIV in the above example does not receive the onclick event because Netscape does not support this event on positioned elements.

Binding to Events

Event Binding is the association between the event and script that executes as a result of the event. For binding to events of the document or positioned elements, they must be bound through code after the page is finished loading. Event handlers defined as attributes are not supported in Netscape. For example, to bind to the onmousedown event handler of the document:

function doMouseDown() {
  // code to run when the mouse goes down
}
function doLoad() {
  setup(); // Initialize the library
  // hookup event handlers
  document.onmousedown = doMouseDown;  // Associates the doMouseDown function with the onmousedown event.
}
window.onload = doLoad;

Event Object

Every event has an event object associated with it. This event object is accessed through the window object. The following properties are exposed on the event object: (this is a subset of the properties available in IE4). All these properties stay constant as the event is bubbling.

cancelBubble A boolean. This property can be used to stop the event from bubbling.
returnValue A boolean. This property is used to override the default action of the event.
clientX Returns the position of the mouse relative to the upper left of the client region.
clientY Returns the position of the mouse relative to the upper left of the client region.
offsetX Returns the position of the mouse relative to the upper left of the coordinate system. (SEE IE4 Notes)
offsetY Returns the position of the mouse relative to the upper left of the coordinate system. (SEE IE4 Notes)
screenX Returns the position of the mouse relative to the screen.
screenY Returns the position of the mouse relative to the screen.
srcElement Returns the element that first fired the event. IE4 and Netscape may not return the same element since IE fires events on all HTML elements. (this works the same in both browsers for images, text controls, positioned elements that contain no HTML, and links (<A HREF=..>) that contain no rich HTML.)
altKey Returns whether the alt key is pressed.
ctrlKey Returns whether the control key is pressed.
shiftKey Returns whether the shift key is pressed.
button Only on mouse events. Returns the button that is pressed (1 for left button)
keyCode Only on keyboard events. Returns the key that is pressed.
type Returns a string representing the event that was fired without the "on" prefix. eg., onclick returns click

Displaying Contents for Older Browsers

To provide content for older browsers, embed a DIV on your page with the style of display: none. For example:

<DIV STYLE="display: none">
  This page does not function properly without 
  Internet Explorer 4.0 or Netscape Navigator 4.0.
</DIV>

Simple Examples

...more to come...

1. Moving an element, pos1, 10 pixels down.

setPosition(document.all.pos1, document.all.style.pixelTop+10)

Do not assign the new value to the pixelTop property. While this will work in IE4, it is not reflected in Netscape. The pixel* properties are updated appropriately after this methods is called.

See www.SiteExperts.com for more examples.

Notes

Performance Information

The library is aproximately 10K which needs to be downloaded with the page. This file should become cached so subsequent pages that use the library from your domain will not incur the cost of an additional download, but they will incur a small cost to parse the script. Internet Explorer 4.0 incurs almost no performance hit beyond loading the code because most of IE's object model is exposed natively. Netscape Navigator takes a small hit after the page is loaded as the library constructs the object hierarchy. A page with a large number of positioned elements may notice a small delay once the page is loaded.

Netscape Navigator 4.0

Below are a few interesting things I learned about positioning in Netscape Navigator. These also should be taken into account when positioning elements and also demonstrates that you should always test your page on both browsers.

  1. CSS does not always inherit into positioned elements.
  2. Backgrounds are not correctly applied to positioned elements unless a border is also specified. The background otherwise only encompasses the individual words rather than the rectangular block. Use a very small border on the positioned element to get around this (eg., <DIV STYLE="position: absolute; background: red; border: .1 white solid">
  3. Do not set an initial background color using CSS if you are going to modify it through script. Netscape has a bug where the background color can only be changed if the color was not initially specified in the source code.
  4. Resizing the window causes often causes painting problems and potentially scripting errors.
  5. Refreshing a page with positioned elements randomly crashes my machine.

Internet Explorer 4.0

If you are familiar with Internet Explorer 4.0's Dynamic HTML object model, below lists how you should restrict your coding. For complete cross-browser compatibility, you can't use most of the richness of Explorer's object model as Navigator has no comparable support to build on.

  1. You should limite event handlers to elements that Netscape supports. eg., <A>, <FORM>, <IMG>, <INPUT>, <TEXTAREA>, and <SELECT>, and positioned Elements.
  2. Netscape has no dynamic style model (styles can only be set during the loading of the page). The only style that can be changed is the background color and visibility of positioned elements. Use the setColor and setVisibility methods.
  3. Events bubble only through the list of elements netscape supports events on, the positioned elements, then the document.
  4. Never use an integer index into the ALL collection as Netscape only exposes a small subset of the elements.
  5. Do not access the ALL collection or positioned elements until the page is loaded.
  6. IE4 Beta 2 has a bug in that it returns offsetX and offsetY when clicking on the document as the same value as the clientX and clientY properties. I emulated this bug in the library so that Netscape will return the same value. In positioned elements, this property returns the correct value. Therefore, these properties should not be used on the document. Use clientX and clientY instead until the final release.

copyright 1997 by Scott Isaacs
www.insideDHTML.com