reptile7's JavaScript blog
Thursday, September 27, 2012
 
The Colored Squares and Their New Homes
Blog Entry #265

Today we will begin modernizing the Expanding Colored Squares Example of Netscape's Dynamic HTML in Netscape Communicator resource. As of this writing I have not been able to update all of the example's JavaScript to my satisfaction, but that's no reason to not get going on the example's HTML and CSS in this post.

Parent layer to div

Two entries ago I identified a key reason why the example's colored squares are not housed in divs: Netscape 4.x supports the width and height attributes for a number of elements, but the div element isn't one of them. Of course, modern browsers duly apply the CSS width and height properties to all block-level elements, giving us the green light to replace the topleftblock, toprightblock, bottomleftblock, and bottomrightblock (document.layers) layer elements with div elements.

"What about the reason you gave in the previous post? 'The widths of div-based layers do not hold when external files are loaded into them.' The HTML DOM's HTMLDivElement interface doesn't have a src attribute - you won't be able to carry out the thislayer.src = thislayer.mysource; operation with a div." True enough: fortunately the point#.htm documents are sufficiently small such that their constituent elements can be brought into or even created in the main document. (I gave fleeting thought to putting the colored squares in iframes but quickly scotched the idea upon realizing that users won't see any non-src iframe content unless their iframe rendering has been turned off.)

The document.layers layer elements have top, left, width, height, and bgcolor presentational attributes; this data is easily moved to a style sheet:

#topleftblock, #toprightblock, #bottomleftblock, #bottomrightblock { position: absolute; width: 200px; height: 200px; }
#topleftblock { top: 50px; left: 50px; background-color: #ff5555; }
#toprightblock { top: 50px; left: 250px; background-color: #5555ff; } ...


We can't clip the divs with a clip element attribute but we can definitely do so via the CSS clip property, which applies to absolutely positioned elements and whose boundary coordinate order begins with the clip.top value and proceeds clockwise (clip.top, clip.right, clip.bottom, clip.left).

#topleftblock { clip: rect(150px, 200px, 200px, 150px); }
#toprightblock { clip: rect(150px, 50px, 200px, 0px); } ...


The document.layers layers were clipped scriptically; we can clip the divs that way too if we want:

document.getElementById("topleftblock").style.clip = "rect(150px, 200px, 200px, 150px)"; ...

As for the layers' onload and onmouseover behavioral attributes, we'll get to those guys later.

Child layer to span

We next consider the nested layers that respectively hold the 1, 2, 3, and 4 numeral headings of the initial example display. As a practical matter I decided to trade in these layers and their h1 children for spans and not divs because I wanted to collectively access the aforediscussed parent divs via a document.getElementsByTagName("div") operation in the JavaScript part of the code (even though divs would probably be more appropriate semantically, given that the nested layers aren't flanked by any content).

#span0, #span1, #span2, #span3 { position: absolute; font: xx-large bold; }
#span0 { left: 168px; top: 160px; }
#span1 { left: 18px; top: 160px; } ...
...
<div id="topleftblock"><span id="span0">1</span></div>
<div id="toprightblock"><span id="span1">2</span></div> ...


The h1 'styling' is roughly reproduced via a font: xx-large bold; style declaration.

The last layer

Something I didn't mention two entries ago:
In the squares.htm source the bottomrightblock layer element is followed by a

<layer top="500"><p></p></layer>

layer element that enables access to all of the fully expanded bottomleftblock and bottomrightblock layers by effectively increasing the height of the squares.htm page if the pre-expansion squares.htm height is less than that of the entire display (450px) - in this case, when the page loads Netscape 4.x provides a vertical scrollbar via which the user can get to the beyond-the-viewport (bottom) parts of the two bottom layers. Even back in the day (when 640 x 480 screen resolutions were the norm) it wasn't necessary to use a layer for this purpose: a document.height = 500; command would have done the trick. A body { height: 500px; } style rule would seem to be the safe cross-browser replacement for the last layer (we noted in the Page dimensions section of Blog Entry #240 that document.height is not supported by IE and Firefox); in practice, the post-Netscape 4.x browsers on my computer either provide initially or generate on the fly (in response to mousing over the 3 or 4 square) a vertical scrollbar for accessing the entire display if the viewport height is less than 450px - no page height-increasing mechanism of any kind is needed.

point#.htm content

Perhaps the easiest way to bring the point#.htm documents into the squares.htm document is to stringify each point#.htm document (body) and place each string in the squares.htm JavaScript; the strings can then be written to the innerHTMLs of the parent divs by either the changeNow( ) or expand( ) function.

var expandedsource = ["<h3>Netscape Navigator</h3><p>Netscape Navigator 4.0 is ...</p>",
    "<h3>Netscape Messenger</h3><p>Netscape Messenger is ...</p>",
    "<h3>Netscape Composer</h3><p>Netscape Composer is ...</p>",
    "<h3>Netscape Netcaster</h3><p>Netscape Netcaster is ...</p>"]; ...
squares = document.getElementsByTagName("div"); ...
squares[n].innerHTML = expandedsource[n];


A related approach:
Put the eight point#.htm elements in a display:none; div in the squares.htm HTML. Give the elements ordinalized ids that allow them to be respectively loaded into the corresponding parent divs.

squares[n].innerHTML = document.getElementById("blockheader" + n);
squares[n].appendChild(document.getElementById("blockpara" + n));
...
<div style="display:none;">
<h3 id="blockheader0">Netscape Navigator</h3><p id="blockpara0">Netscape Navigator 4.0 is ...</p>
<h3 id="blockheader1">Netscape Messenger</h3><p id="blockpara1">Netscape Messenger is ...</p> ...
</div>


Alternatively, you can create the point#.htm elements from scratch in the squares.htm JavaScript:

var headerArray = new Array(4), paraArray = new Array(4);
var headerText = ["Netscape Navigator", "Netscape Messenger", "Netscape Composer", "Netscape Netcaster"];
var paraText = ["Netscape Navigator 4.0 is ...", "Netscape Messenger is ...", "Netscape Composer is ...", "Netscape Netcaster is ..."];
for (i = 0; i < squares.length; i++) {
    headerArray[i] = document.createElement("h3");
    headerArray[i].textContent = headerText[i];
    paraArray[i] = document.createElement("p");
    paraArray[i].textContent = paraText[i]; }


Parent div initialization

The differing coordinate requirements of the colored square expansions/contractions notwithstanding, the example's four initialization functions can be consolidated into a single window.onload-triggered function by pre-arraying the values of the various initialization properties à la the expandedsource array of the previous section.

CSS does not have individual clip.top, clip.right, clip.bottom, and clip.left properties, but we can define matching ctop, cright, cbottom, and cleft custom properties and attach them to the parent divs.

window.onload = function ( ) {
    var cliptop = [maxclipcontracted, maxclipcontracted, minclip, minclip];
    var clipright = [maxclip, minclipcontracted, maxclip, minclipcontracted];
    var clipbottom = [maxclip, maxclip, minclipcontracted, minclipcontracted];
    var clipleft = [maxclipcontracted, minclip, maxclipcontracted, minclip];
    squares = document.getElementsByTagName("div");
    for (i = 0; i < squares.length; i++) {
        squares[i].status = "waitingToExpand";
        squares[i].ctop = cliptop[i];
        squares[i].cright = clipright[i];
        squares[i].cbottom = clipbottom[i];
        squares[i].cleft = clipleft[i]; }


The status, dtop/dright/dbottom/dleft, myposition, mysource, and mytext custom properties that are attached to the document.layers layers can be transferred as is to the parent divs. Excepting the status property, the values of these properties do not change and we therefore have the option of making them 'top-level' properties, i.e., it is not necessary to associate them with the parent divs.

var dtop = [-delta, -delta, 0, 0];
var dright = [0, delta, 0, delta];
...
window.onload = function ( ) { ... }


We are now ready to take on the mouseover-triggered expansion/contraction functions - we'll hit 'em with our best shot in the following entry.

Monday, September 17, 2012
 
The Quadrophonic Unfurl, Part 2
Blog Entry #264

We return now to our analysis of the Expanding Colored Squares Example of Netscape's Dynamic HTML in Netscape Communicator resource. In today's post we will discuss the example's changeNow( ), expand( ), and contract( ) functions, which apply to all four of the example's colored square-holding layers.

Change it, now

Having detailed the initialization of the topleftblock layer in our previous episode, we are ready to expand and contract the layer's 1 colored square. Both expansion and contraction of the colored square are mediated by a changeNow( ) function, which is triggered by mousing over the square (at least on my computer, mousing over the invisible part of the topleftblock layer does not call the changeNow( ) function).

function changeNow(n) {
    var thislayer = document.layers[n];
    if (thislayer.status == "waitingToExpand") {
        thislayer.src = thislayer.mysource;
        expand(n); }
    else if (thislayer.status == "waitingToContract") {
        contract(n); }
    return false; }
...
<layer id="topleftblock" ... onmouseover="changeNow(0);"> ... </layer>


As for the initializeTopLeft( ) function discussed in the previous post:
(i) The topleftblock layer's document.layers[i] index, 0, is passed to the changeNow( ) function.
(ii) The 0 index is given an n identifier.
(iii) n is plugged into a document.layers[ ] expression to get the topleftblock layer.
(iv) The topleftblock layer is given a thislayer identifier.
These operations were unnecessary for the initializeTopLeft( ) function but we need them or their equivalent here because the example's other document.layers also call on the changeNow( ) function for the expansion and contraction of their visible regions; they can be simplified by
(a) passing a this object reference to the changeNow( ) function and then
(b) giving the this argument a thislayer identifier.

Next, an if statement checks if thislayer has a waitingToExpand status: check. Subsequently:

(1) The topleftblock layer's child layer holding the 1 numeral is overwritten with the point1.htm file by assigning thislayer.mysource to thislayer.src. Reason #2 why the colored squares are not housed in divs: the widths of div-based layers do not hold when external files are loaded into them, as we observed two entries ago. FYI: This assignment constitutes a load event and therefore re-calls the initializeTopLeft( ) function, which then clips the topleftblock layer a second time - that's why this operation is carried out now and not post-expansion.

(2) An expand( ) function is called and passed the n index.

If thislayer's status were waitingToContract (vide infra), then a contract( ) function would be called and passed the n index. The changeNow( ) function concludes with a return false; statement whose purpose eludes me - indeed, commenting it out has no effect as far as I can tell.

Square expansion

The expand( ) function expands the topleftblock layer's 1 colored square leftward and upward à la the squaresdemo0 demo of the previous post.

function expand(n) {
    var thislayer = document.layers[n]; ...


The expand( ) function begins by...ah, we don't need to go through this again, do we? Suffice it to say that we could pass the thislayer reference itself to expand( ) in the same way and then use the thislayer argument in the statements that follow.

thislayer.status = "expanding";

Before expanding the 1 square, the expand( ) function first sets thislayer's status to expanding. Now, if the user mouses over the square and lets the mouse cursor sit until the square has finished expanding - and that's what the overwhelming majority of users are going to do - then the above statement is unnecessary. However, it is possible (but highly unlikely, given how quickly the square expands) that the user might instead wildly move the mouse cursor around as the square is expanding. Suppose the user darts the mouse cursor in and out of the square during the expansion: this would result in spastic square motion if thislayer's status were still waitingToExpand as changeNow( ) would be re-called, point1.htm would be reloaded into thislayer, initializeTopLeft( ) would be re-called and thislayer would be clipped again, expand( ) would be re-called, etc. - the expanding status is meant to choke off this chain of events.

Let's get expanding, shall we?

thislayer.clip.left = thislayer.clip.left + thislayer.dleft;
thislayer.clip.top = thislayer.clip.top + thislayer.dtop;
thislayer.clip.right = thislayer.clip.right + thislayer.dright;
thislayer.clip.bottom = thislayer.clip.bottom + thislayer.dbottom;


Per the dleft, dtop, dright, and dbottom values set by the initializeTopLeft( ) function (-delta, -delta, 0, and 0, respectively), thislayer's clip.left and clip.top values drop by 10 and its clip.right and clip.bottom values remain unchanged, giving a 60px-by-60px square that doesn't show any of the point1.htm content yet:

The example display after the first expansion of the topleft colored square

The preceding statements can be written more compactly via the += assignment operator:

thislayer.clip.left += thislayer.dleft;
thislayer.clip.top += thislayer.dtop; ...


More generally, in all four initialization functions the dleft/dtop/dright/dbottom (d*) property definitions are such that the properties expand the colored squares when they are added to their matching clip.* properties; as a result, the toprightblock, bottomleftblock, and bottomrightblock layers are also able to use the expand( ) function for their square expansions.

Expansion is continued or not via the following conditional:

/* Is the layer fully contracted? True if: The square is the top OR bottom left AND its clip left is less than or equal to the minimum clip for contracted squares OR the square is the top OR bottom right AND its clip right is greater than or equal to the max clip for contracted squares. */

if ((((thislayer.myposition == "topLeft") | (thislayer.myposition == "bottomLeft")) && (thislayer.clip.left >= minclip)) ||
(((thislayer.myposition == "topRight") | (thislayer.myposition == "bottomRight")) && (thislayer.clip.right <= maxclip)))
    window.setTimeout("expand(" + n + ");", 50);
else thislayer.status = "waitingToContract";


• The conditional is preceded by a problematic and poorly worded comment; assuming that we want the colored square to fill the original topleftblock layer and not go beyond that, the comment should say, "Is the square not fully expanded? True if the square is held by the topLeft or bottomLeft layer and the layer's clip.left value hasn't hit 0 yet..."

• The topleftblock layer can be flagged here by a thislayer.name == "topleftblock" comparison - it is not necessary to use a custom property to do so.

• Oddly, the thislayer.myposition == "topLeft" and thislayer.myposition == "bottomLeft" subconditions are boolean-wise compared via the | bitwise operator as opposed to the || logical operator. This turns out to not be a problem: although the | operator expects number operands, the true and false booleans respectively convert to 1 and 0 in the context of a | operation. For the topleftblock layer, 1 | 0 returns 1.

• Not previously discussed, the minclip operand appearing in the thislayer.clip.left >= minclip subcondition is a global variable that is set to 0 prior to the initializeTopLeft( ) function.

• The if clause is operative as long as the thislayer.clip.left >= minclip subcondition returns true (1 && true returns true). The subcondition's use of the >= operator means that the subcondition returns true when the colored square has filled the topleftblock layer; as a result, one last expand( ) run occurs, thislayer's clip.left and clip.top values end at -10 and not 0, and the fully expanded square measures 210px by 210px. To the extent that this bothers you, stopping the square at the original layer boundaries is no more difficult than replacing >= with >.

• The setTimeout( ) command can alternately be written as window.setTimeout(expand, 50, n);. (This syntax doesn't work with IE, but then again, the DHiNC examples weren't meant for IE in the first place.) If you pass a thislayer argument to the expand( ) function, then you'll have to use the window.setTimeout(expand, 50, thislayer); syntax as window.setTimeout("expand(" + thislayer + ");", 50); throws a missing ] after element list error for a reason beyond my understanding.

• As determined by the above code, the expand( ) expansion loop runs for 16 iterations. When thislayer.clip.left and thislayer.clip.top reach their final value(s), the else clause fires and sets thislayer's status to waitingToContract.

Here's the final result:

The example display when expansion of the topleft colored square is complete

Other square expansions

(2) The 2 square expands upward and rightward: for the parent toprightblock layer, clip.top decreases, clip.right increases, and clip.left and clip.bottom do not change.

(3) The 3 square expands leftward and downward: for the parent bottomleftblock layer, clip.left decreases, clip.bottom increases, and clip.top and clip.right do not change.

(4) The 4 square expands rightward and downward: for the parent bottomrightblock layer, clip.right increases, clip.bottom increases, and clip.left and clip.top do not change.

Square contraction

Mousing out from a fully expanded colored square and then mousing over the square causes the square to contract to its original state via the aforementioned contract( ) function. Returning to the

The fully expanded topleft colored square

colored square, the contract( ) function first gets the topleftblock layer and then sets its status to contracting in order to head off any mouseover mischief (vide supra).

function contract(n) {
    var thislayer = document.layers[n];
    thislayer.status = "contracting"; ...


In the contract( ) function, contraction is carried out by subtracting thislayer's d* properties from its clip.* properties:

thislayer.clip.left = thislayer.clip.left - thislayer.dleft;
thislayer.clip.top = thislayer.clip.top - thislayer.dtop;
thislayer.clip.right = thislayer.clip.right - thislayer.dright;
thislayer.clip.bottom = thislayer.clip.bottom - thislayer.dbottom;


Yes, these statements are good for all four document.layers; yes, we could be using the -= operator here. For the topleftblock layer, clip.left and clip.top increase by 10* and clip.right and clip.bottom remain unchanged, giving a 200px-by-200px square that fills (no longer overflows) the original layer.
(*These operations merely shave off excess margin-left and margin-top generated by the expand( ) function - I trust that I don't need to show you a picture of the resulting square.)

Contraction continues via the following if statement:

if ((((thislayer.myposition == "topLeft") | (thislayer.myposition == "bottomLeft")) && (thislayer.clip.left < minclipcontracted)) ||
(((thislayer.myposition == "topRight") | (thislayer.myposition == "bottomRight")) && (thislayer.clip.right > maxclipcontracted)))
    window.setTimeout("contract(" + n + ");", 50);


Not previously discussed, the minclipcontracted operand appearing in the thislayer.clip.left < minclipcontracted subcondition is a global variable that is set to 50 prior to the initializeTopLeft( ) function. The thislayer.clip.left < minclipcontracted subcondition means that thislayer.clip.left and thislayer.clip.top only get as far as 50

The example display when thislayer.clip.left is equal to minclipcontracted

before the square snaps back to its original state via an accompanying else clause, i.e., thislayer.clip.left and thislayer.clip.top do not smoothly increase over the 100 pixels separating each pair of minclipcontracted and maxclipcontracted boundaries. Here's that else clause:

else {
    thislayer.status = "waitingToExpand";
    thislayer.document.write(thislayer.mytext);
    thislayer.document.close( ); }


The else clause first sets thislayer's status to waitingToExpand even though we're not done contracting yet. Next, a write( ) command writes thislayer's original mytext content - the <layer top='160' left='168'><h1>1</h1></layer> child layer - to thislayer's document, thereby overwriting the point1.htm content; the write( ) command does not need to be preceded by an open( ) command but it does need to be followed by a close( ) command. (Unlike IE 4.x, Netscape 4.x does not support the innerHTML property, so we have to go about this writing business, which is documented in the Writing Content in Positioned Blocks section of the DHiNC resource, somewhat more circuitously.) The close( ) operation constitutes a load event and consequently re-calls the initializeTopLeft( ) function, which finishes the contraction by reclipping the topleftblock layer to its original state.

In sum, the contract( ) function runs only 6 times and it does less than half of the actual contracting, although you can change that by deploying thislayer.clip.left < maxclipcontracted and thislayer.clip.right > minclipcontracted subconditions in the above if condition.

I trust that you can handle the other document.layers colored square contractions at this point.

Our next task is to get this thing to work with modern browsers, and we'll get cracking on it in the following entry.

Wednesday, September 05, 2012
 
I Unfurl the Layers Quadrophonic
Blog Entry #263

In today's post we will take up the Expanding Colored Squares (ExColSq) Example of Netscape's Dynamic HTML in Netscape Communicator resource. The ExColSq Example offers a script that dynamically changes the clipping (visible) regions of four connected layers in response to mouseover events.

The ExColSq Example is reminiscent of the HTML Goodies JavaScript Script Tips #76-78 Script, which we covered in Blog Entries #94 and #95. The Script Tips #76-78 Script codes a yellow, name="click" layer whose visible region
(a) rolls downward, thereby exposing a table of initially invisible links, when mouseovered, and
(b) rolls up to its original state when mouseouted.
All of the Script Tips #76-78 Script rolling action occurs along the y-axis; moreover, at no point does the content of the click layer change.

In contrast, each colored square of the ExColSq Example expands and contracts in two dimensions at once, as though along a diagonal; in addition, the square's content is changed when the square leaves or returns to its fully contracted state. To give you a taste of what I'm talking about, mouseover the 1 square in the div below, and then mouseout the expanded square generated by your mouseover:

1
 
Netscape provided a single, layer element-based squares.htm version of the example, so that's what we'll be working with in the discussion that follows. Initial layout The colored squares of the example are laid out in a 2-by-2 grid. When all of the squares are fully expanded, the example display is: The colored squares, fully expanded Each square is held by a layer whose starting dimensions are 200px by 200px; however, in its fully expanded state the square measures 210px by 210px, a discrepancy that we'll sort out later. When the squares.htm page loads, the square layers are clipped so that only 50px-by-50px corners thereof are visible: The colored squares, fully contracted Here's the HTML for the upper left layer: <layer id="topleftblock" top="50" left="50" width="200" height="200" bgcolor="#ff5555" onload="initializeTopLeft(0);" onmouseover="changeNow(0);"> <layer top="160" left="168"><h1>1</h1></layer> </layer> The attributes of the layer element are detailed in the Attributes and Properties section of the DHiNC resource. • The topleftblock layer's top and left attributes position the layer (its upper left vertex) 50 pixels below the viewport's top edge and 50 pixels to the right of the viewport's left edge. • As noted above, the topleftblock layer's width and height are both initialized to 200 pixels. Reason #1 why the squares are not housed in divs: Netscape 4.x supports the width and height attributes for a number of elements, but the div element isn't one of them. Netscape 4.x can set a width="200" for a group of class="divClass" divs via a document.classes.divClass.div.width = "200px"; style statement, but classical JavaScript's style object doesn't even have a height property. • The topleftblock layer element has a layer element child - let's call it var nestedlayer0 = document.topleftblock.document.layers[0]; - that holds an h1 element containing a 1 numeral. The nestedlayer0 layer has a shrink-to-fit width and an effective height of 100%, measuring 16px by 40px; with respect to the top and left edges of its topleftblock layer parent, the nestedlayer0 layer is given top and left offsets that approximately center the 1 in the visible region of the topleftblock layer. Unlike the topleftblock layer, the nestedlayer0 layer could definitely be recast as a div; however, as the 1 is not a heading semantically, we will trade in the nestedlayer0 layer and h1 elements for a suitably styled span element in due course. Clip it The topleftblock layer could be clipped with a clip="150,150,200,200" attribute*; it is instead clipped by an initializeTopLeft( ) function, which is called when the layer has loaded. *According to Netscape the layer should also be clippable by a clip: rect(150,150,200,200); style declaration, but this doesn't work on my computer (maybe it's a Windows-only thing). var maxclipcontracted = 150; var maxclip = 200; ... function initializeTopLeft(n) {     var thislayer = document.layers[n]; ...     thislayer.clip.left = maxclipcontracted;     thislayer.clip.top = maxclipcontracted;     thislayer.clip.right = maxclip;     thislayer.clip.bottom = maxclip; ... } The layer object's various clip.* properties are summarized here in the DHiNC resource. The topleftblock layer's document.layers[i] index, 0, is passed to the initializeTopLeft( ) function and given an n identifier; n is then used to get the topleftblock layer, which is given a thislayer identifier. These operations are unnecessary as we could access the topleftblock layer in the initializeTopLeft( ) function via a document.topleftblock expression. A set of four statements clips thislayer to size: (1) The thislayer.clip.left = maxclipcontracted; statement sets the left edge of thislayer's visible region 150 (maxclipcontracted) pixels to the right of thislayer's left edge. (2) The thislayer.clip.top = maxclipcontracted; statement sets the top edge of thislayer's visible region 150 pixels below thislayer's top edge. (3) The thislayer.clip.right = maxclip; statement sets the right edge of thislayer's visible region 200 (maxclip) pixels to the right of thislayer's left edge. (4) The thislayer.clip.bottom = maxclip; statement sets the bottom edge of thislayer's visible region 200 pixels below thislayer's top edge. Netscape illustrates the clipping process with a "Clip values" figure: The Expanded Colored Squares Example's 'Figure 12.4 Clip values' There are some mistakes in the figure: • If we were to demarcate the visible region of the topleftblock layer with a clip attribute or style declaration, then we would specify the boundary coordinates in the following order: (clip.left, clip.top, clip.right, clip.bottom), i.e., we would begin with clip.left and proceed clockwise. (N.B. This is not the W3C's clip coordinate order, which begins with the clip.top value and proceeds clockwise.) • The layer's lower left vertex would correspond to a (0,200,0,200) clip value; a clip="0,0,200,200" setting would 'clip' the layer at its original boundaries and thus have no effect on it. • The layer's upper right vertex would correspond to a (200,0,200,0) clip value; a clip="0,200,0,0" setting is nonsensical as its clip.bottom value is less than its clip.top value. Other initialization The initializeTopLeft( ) function also equips the topleftblock layer with eight custom properties that will come into play when the expansion/contraction action gets under way. (1-4) var delta = 10; function initializeTopLeft(n) { ...     thislayer.dleft = -delta;     thislayer.dtop = -delta;     thislayer.dbottom = 0;     thislayer.dright = 0; ... When the visible region of the topleftblock layer expands, the layer's clip.left and clip.top values decrease; when it contracts, clip.left and clip.top increase; for both expansion and contraction, clip.right and clip.bottom do not change. In conjunction with a global delta variable, dleft, dtop, dright, and dbottom properties quantify the steps of the expansion and contraction movement. (5) thislayer.status = "waitingToExpand"; Expansion and contraction of the topleftblock layer's visible region are respectively effected by expand( ) and contract( ) functions. A status property connects both expand( ) and contract( ) to an onmouseover="changeNow(0);" event handler and is also used to prevent the stacking of expand( ) and contract( ) calls. The status property is initialized to a waitingToExpand string. (6) thislayer.mysource = "point1.htm"; Immediately prior to the initiation of expansion an external point1.htm file holding the expanded square content is loaded into the topleftblock layer; a mysource property associates the topleftblock layer with the point1.htm file. There's not much to point1.htm: <h3>Netscape Navigator</h3> <p>Netscape Navigator 4.0 is the newest version of Netscape's world-leading software for browsing information on intranets or the Internet.</p>   point1.htm's h3 and p elements are styled by the squares.htm document with the following rules: h3 { text-align: center; margin-top: 4%; } p { margin-left: 10%; margin-right: 10%; } (7) thislayer.mytext = "<layer top='160' left='168'><h1>1</h1></layer>"; At the end of contraction the point1.htm text is overwritten with the layer's original content; a mytext property is set to this content in stringified form. (8) thislayer.myposition = "topLeft"; Lastly and least, the layer is given a myposition property whose value, topLeft, will later serve as an identifier: this assignment is unnecessary as the layer already has an id.
Each of the other three layers has a similar definition, and a corresponding initialization function.
The 2 square is held by a toprightblock layer whose left and top offsets cause its left edge to coincide with the right edge of the topleftblock layer; loading the toprightblock layer calls an initializeTopRight( ) function that clips the layer accordingly and equips it with the aforespecified custom properties set to toprightblock-appropriate values. And so on for the 3 and 4 squares. We'll work through the expansion and contraction of the topleftblock layer's visible region in the following post.


Powered by Blogger

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