- Cross-Browser Issues
- Detecting the User's Browser
- Creating a Custom Object Front End
Creating a Custom Object Front End
The library of cross-browser code that I'll introduce to you in the rest of this chapter uses as its base a custom object front end, as described in general terms earlier in this chapter. More specifically, I use code to create a custom object for every <div> and <span> tag in the current document because these are the elements that you can manipulate via DHTML in all three object models.
The next couple of sections show you the structure of these custom objects as well as the code that constructs them.
Examining the Object
Listing 1 shows the dhtml_object() constructor function that's used to create each custom object.
Listing 1: The Constructor Function for the Custom Object
function dhtml_object (obj, css, id) { this.obj = obj this.css = css this.id = id this.left = get_left this.right = get_right this.top = get_top this.bottom = get_bottom this.width = get_width this.height = get_height this.visibility = get_visibility this.zIndex = get_zIndex this.move_to = move_to this.move_by = move_by this.set_left = set_left this.set_top = set_top this.set_width = set_width this.set_height = set_height this.set_visibility = set_visibility this.set_zIndex = set_zIndex this.move_above = move_above this.move_below = move_below this.set_backgroundColor = set_backgroundColor this.set_backgroundImage = set_backgroundImage this.set_html = set_html this.get_clip_top = get_clip_top this.get_clip_right = get_clip_right this.get_clip_bottom = get_clip_bottom this.get_clip_left = get_clip_left this.get_clip_width = get_clip_width this.get_clip_height = get_clip_height this.resize_clip_to = resize_clip_to this.resize_clip_by = resize_clip_by }
Table 1 summarizes the properties and methods in this object.
Table 1 Properties and Methods of the Custom Object
Property/Method |
Description |
Properties |
|
obj |
The object to which the custom object serves as a front end. |
css |
A reference that specifies the property that the surfer's browser uses to access CSS style properties (more on this a bit later). |
id |
The original object's id value. |
Properties Implemented as Functions |
|
left |
The position, in pixels, of the left edge of the object. This "property" is actually the result of the custom get_left() function. |
right |
The position, in pixels, of the right edge of the object, as given by the custom get_right() function. |
top |
The position, in pixels, of the top edge of the object, as given by the custom get_top() function. |
bottom |
The position, in pixels, of the bottom edge of the object, as given by the custom get_bottom() function. |
width |
The width, in pixels, of the object, as given by the custom get_width() function. |
height |
The height, in pixels, of the object, as given by the custom get_height() function. |
visibility |
The visibility style of the object, as given by the custom get_visibility() function. |
zIndex |
The z-index of the object, as given by the custom get_zIndex() function. |
Methods Implemented as Functions |
|
move_to |
Moves the object to the specified position. |
move_by |
Moves the object by the specified amount. |
set_left |
Sets the position of the object's left edge. |
set_top |
Sets the position of the object's top edge. |
set_width |
Sets the object's width. |
set_height |
Sets the object's height. |
set_visibility |
Sets the object's visibility. |
set_zIndex |
Sets the object's z-index. |
move_above |
Moves the object on top of a specified object. |
move_below |
Moves the object below a specified object. |
set_backgroundColor |
Sets the object's background color. |
set_backgroundImage |
Sets the object's background image. |
set_html |
Sets the tags and text that appear inside the object. |
get_clip_top |
Gets the position of the top edge of the object's current clipping region. |
get_clip_right |
Gets the position of the right edge of the object's current clipping region. |
get_clip_bottom |
Gets the position of the bottom edge of the object's current clipping region. |
get_clip_left |
Gets the position of the left edge of the object's current clipping region. |
get_clip_width |
Gets the width of the object's current clipping region. |
get_clip_height |
Gets the height of the object's current clipping region. |
resize_clip_to |
Resizes the object's current clipping region to the specified coordinates. |
resize_clip_by |
Resizes the object's current clipping region by the specified amounts. |
Cross-Browser Style References
Of the various properties and methods shown in Table 1, one of the most important from a cross-browser point of view is the css property. This property holds information on how the user's browser refers to styles. To see why this is important, let's look again at how each of the three object models refer to styles.
For the W3C DOM, you first get a reference to an object using getElementById() and then access the style property. For example, here's some code that gets a reference to a <div> tag with id equal to my_div and then sets the element's left style:
document.getElementById("my_div").style.left = 0
For Internet Explorer 4's DHTML DOM, you use document.all to get a reference to the element and then use the style property. Here's an example:
document.all.my_div.style.left = 0
For Netscape 4's LDOM, you use document.layers to get a reference to the element and then set the style attribute directly. Here's an example:
document.layers.my_div.left = 0
These are quite different, as you can see. To "hide" this difference from your code, the custom dhtml_object uses its css property, which holds the object reference followed by whatever the browser uses to access styles. Here's what the css property stores for the above examples:
W3C DOM: document.getElementById("my_div").style
Internet Explorer 4: document.all.my_div.style
Netscape 4: document.layers.my_div
The custom object hides all this inside css, so to set any style, you use the following syntax:
Custom_Object.css.Style = Value
Custom_Object |
A reference to the custom object |
Style |
The name of the style |
Value |
The value of the style |
For example, if the current_object variable references one of these custom objects, you'd use the following statement to set the value of the left style to 0:
current_object.css.left = 0
Creating the Custom Objects
Before you can use the properties and methods of the dhtml_object, you have to create one of these custom objects for every <div> and <span> tag in your page. That's the job of the code in Listing 2.
Listing 2: Creating the Custom Objects
// This array holds all of the document's DHTML-able objects var dhtml_objects = new Array() // This function creates the custom objects // that serve as cross-browser front-ends function create_object_array() { // All the <div> and <span> tags are stored in these variables var div_tags var span_tags var css_tags // Is the browser W3C DOM compliant? if (document.getElementById) { // If so, use getElementsByTagName() to get the <div> tags div_tags = document.getElementsByTagName("div") // Loop through the <div> tags for (var counter = 0; counter < div_tags.length; counter++) { // Store the current object current_object = div_tags[counter] // Store how the browser accesses styles object_css = current_object.style // Store the object's id object_id = current_object.id // Only store those tags that have an id if (object_id) { // Create a new dhtml_object and store it in dhtml_objects dhtml_objects[object_id] = new dhtml_object(current_object, object_css, object_id) } } // Use getElementsByTagName() to get the <span> tags span_tags = document.getElementsByTagName("span") // Loop through the <span> tags for (var counter = 0; counter < span_tags.length; counter++) { // Store the current object current_object = span_tags[counter] // Store how the browser accesses styles object_css = current_object.style // Store the object's id object_id = current_object.id // Only store those tags that have an id if (object_id) { // Create a new dhtml_object and store it in dhtml_objects dhtml_objects[object_id] = new dhtml_object(current_object, object_css, object_id) } } } // Is the browser DHTML DOM compliant? else if (document.all) { // If so, use document.all to get the <div> tags div_tags = document.all.tags("div") // Loop through the <div> tags for (var counter = 0; counter < div_tags.length; counter++) { // Store the current object current_object = div_tags[counter] // Store how the browser accesses styles object_css = current_object.style // Store the object's id object_id = current_object.id // Only store those tags that have an id if (object_id) { // Create a new dhtml_object and store it in dhtml_objects dhtml_objects[object_id] = new dhtml_object(current_object, object_css, object_id) } } // Use document.all to get the <span> tags span_tags = document.all.tags("span") // Loop through the <span> tags for (var counter = 0; counter < span_tags.length; counter++) { // Store the current object current_object = span_tags[counter] // Store how the browser accesses styles object_css = current_object.style // Store the object's id object_id = current_object.id // Only store those tags that have an id if (object_id) { // Create a new dhtml_object and store it in dhtml_objects dhtml_objects[object_id] = new dhtml_object(current_object, object_css, object_id) } } } // Is the browser LDOM compliant? else if (document.layers) { // Use document.layers to get the positioned <div> and <span> tags css_tags = document.layers // Loop through the layers for (var counter = 0; counter < css_tags.length; counter++) { // Store the current object current_object = css_tags[counter] // Store how the browser accesses styles object_css = current_object // Store the object's id object_id = current_object.id // Only store those tags that have an id if (object_id) { // Create a new dhtml_object and store it in dhtml_objects dhtml_objects[object_id] = new dhtml_object(current_object, object_css, object_id) } } } }
This script opens by declaring the global dhtml_objects array, which will hold the custom objects created for each <div> and <span> tag. The script then runs the create_object_array() function, which is used to add the custom objects to the dhtml_objects array.
The function begins by declaring the div_tags, span_tags, and css_tags variables, which are used to hold the collections of <div> and <span> elements in the page. Then the function performs some object detection, which in broad strokes looks like this:
if (document.getElementById) { Work with the elements using W3C DOM code } else if (document.all) { Work with the elements using DHTML DOM code } else if (document.layers) { Work with the elements using LDOM- code }
For the W3C DOM branch, the function first uses the getElementsByTagName() method to return a collection of the document's <div> elements, which is stored in the div_tags variable. Then a for() loop runs through all the <div> elements and performs five tasks for each element:
It stores the element itself in current_object.
It stores how the element accesses styles in object_css.
It stores the element's id in object_id.
It checks to see if the element has an id value (we want to ignore those that don't have one).
It calls the dhtml_object() constructor function to create a custom object for the element. Note that the current_object, object_css, and object_id variables are passed as the function's obj, css, and id arguments. The resulting object is stored in the global dhtml_objects array.
The function then repeats this process for the document's <span> tags.
For the DHTML DOM branch, the function does basically the same thing. The major difference is that it uses document.all.tags to return the <div> and <span> collections.
The LDOM branch is shorter because the function gets all the positioned <div> and <span> tags in one shot by using document.layers.
Using a Custom Object
It's important to note here that the index of the dhtml_objects array that's assigned to each custom object is not the usual numeric value starting at 0. Instead, the index is the object_id value, so that's how you refer to one of these objects in the array. For example, if a <div> element has an id equal to my_div, then the following expression refers to that element's custom object in the dhtml_objects array:
dhtml_objects["my_div"]
From here, you access the custom object's properties and methods just as you would any object. For example, the following expression returns the my_div custom object's id property:
dhtml_objects["my_div"].id