reptile7's JavaScript blog
Monday, November 05, 2012
32 °F and Falling
Blog Entry #269

In this post we will begin discussing some of the JavaScript material at Lissa Explains It All, a Web site that provides basic information about creating Web pages and getting them on the Web; in particular we will check over the scripts offered by Section 1, Section 7, and Section 8 of the site's JavaScript subsector. The visual effects of these scripts are pretty cool: they include falling snow, a string that chases the mouse cursor, a bouncing image that leaves a trail, and even fireworks.

With one exception, the Sections 1/7/8 scripts are labeled "IE only", which is true in the sense that IE is the only modern browser that will run them. However, these scripts were not designed to be IE only. Written in the late 1990s, they all contain layer object code that enables them to be run by Netscape 4.x. (I've tested them with Communicator 4.61 in the SheepShaver environment, and they check out.) Our task is to update the scripts and to create cross-browser demos for them.

With no further ado, let's get going on the first Section 1 offering, a falling snow script authored by Altan d.o.o. A .zipped snowinstructions.txt file containing the script plus some commentary from Lissa can be downloaded here.

Lissa provides a hearts.html demo page that illustrates the script with a falling image, which can be downloaded as an abheart4.gif file at Lissa's Cursor Images page. Per the above discussion, the demo works with IE 4+ and Netscape 4.x but not with other browsers. (Actually, the demo might work with some older versions of Opera but it definitely does not work with newer versions of Opera.)

As for my own demo, here it is:

Let it snow! Let it snow! Let it snow! Winter is coming, and you may get some snow where you live although it's highly unlikely we'll see any here in the Crescent City.

BTW, an updated version of Altan's script is posted here (the snow3.gif image used by my demo comes from this page); we will look at this code later but for now we will work with the original code offered by Lissa's site.

Cross-browser obstacles

The falling snow script contains some cross-browser configuration code but is otherwise divided into separate Netscape and IE sections for creating, positioning, and moving the snowflakes; respective access to these sections is mediated by ns4up and ie4up gatekeepers.

var ns4up = (document.layers) ? 1 : 0;
var ie4up = (document.all) ? 1 : 0;

The ns4up parts of the code
(1) get the dimensions of the viewport by reading window.innerWidth and window.innerHeight,
(2) house the snowflakes in layer elements, and
(3) position/move the snowflakes via the layer object's top and left properties.

(1) is OK for most modern browsers (innerWidth/innerHeight are supported by IE 9+ but not by earlier IE versions) but (2) and (3) are only OK for Netscape 4.x.

Conversely, the ie4up parts of the code
(A) get the dimensions of the viewport by reading document.body.clientWidth and document.body.clientHeight,
(B) house the snowflakes in div elements, and
(C) position/move the snowflakes via document.all(divID).style.pixelTop and document.all(divID).style.pixelLeft expressions.

(A) is OK for modern browsers (Netscape's clientWidth/clientHeight support goes back to Netscape 7), as is (B). As for (C), modern browsers support document.all in a non-boolean context but the proprietary CSS pixelTop and pixelLeft properties are not supported by Mozilla's browsers; however, it is simple enough to respectively replace pixelTop and pixelLeft with their standard top and left counterparts*.

*pixelTop/pixelLeft and top/left are not exactly equivalent in that the former's values have a number type whereas the latter's values have a string type; we will want to append px unit strings to the latter's values.

We can profitably use the ie4up code as our base for a modern cross-browser script; the ns4up code can and should be thrown out. The ie4up code parts are wrapped in if (ie4up) { ... } statements that lock out modern non-IE browsers, for which the ie4up/document.all condition returns false (we previously discussed the somewhat schizophrenic approach of these browsers to document.all support in Blog Entry #244). To allow non-IE access to the ie4up code, you can replace the document.all test with a document.getElementById test or you can just throw out the if (ie4up) { ... } wrappers altogether.

Snowflake creation

A no variable sets the number of snowflakes in the display; a snowflake variable holds the URL of the snowflake image.

var no = 15;
var snowflake = "snow3.gif";

A no-iteration for loop creates and writes to the page no div elements that individually contain an img element whose src is set to snowflake.

for (i = 0; i < no; ++i) {     ...     if (ie4up) {         if (i == 0) {             document.write("<div id='dot"+ i +"' style='position: ");             document.write("absolute; z-index: "+ i +"; visibility: ");             document.write("visible; top: 15px; left: 15px;'><img src='");             document.write(snowflake + "' border='0'></div>");         } else {             document.write("<div id='dot"+ i +"' style='position: ");             document.write("absolute; z-index: "+ i +"; visibility: ");             document.write("visible; top: 15px; left: 15px;'><img src='");             document.write(snowflake + "' border='0'></div>"); } } }

The divs are respectively given ordinalized ids: dot0, dot1, dot2, etc.

The divs are collectively given position, z-index, visibility, top, and left style settings; the position:absolute; style is necessary but the others aren't:
(a) The divs are added to the document body in source order and are thus z-stacked in source order (à la the pole/fish images of the DHiNC Swimming Fish Example), so we don't need to give them z-indexes.
(b) The initial value of the CSS visibility property is already visible.
(c-d) The top:15px;left:15px; declaration set unnecessarily specifies an initial position for the divs before they are distributed across the viewport; letting top and left default to auto places the divs at their normal-flow position(s), which is good enough for our purposes.

None of the browsers on my computer imparts a default border to an image; you can keep the border='0' attribute (or, given its deprecation, replace it with a corresponding style rule) if you want but I would get rid of it.

Is there any reason to deal with the dot0 div via the if (i == 0) { ... } statement and then use a separate else clause for the remaining divs? None whatsoever. In his updated code (vide supra), Altan does wrap the dot0 div's image in an <a href=''> ... <\/a> anchor, but I fail to see the point of this.

For that matter, do we need the div containers in the first place? Nope - there's no reason not to directly manipulate the images themselves. Putting it all together, the snowflake creation code can be simplified to:

img { position: absolute; }
for (i = 0; i < no; ++i) { document.write("<img id='dot" + i + "' src='" + snowflake + "'>"); }

We're ready to strew our snowflakes across the page and get the snowing action under way - we'll go through the script's snow mechanics in detail in the following entry.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)