Hypermedia Production, Fall 1998
Using External Files for Stretchtext

As we noted last week, a stretchtext document may become ungainly if all the textual variants are included in the main markup. As an alternative, consider storing insert material in external files as shown in our second stretchtext demo, posted this week.

This technique entails a bit of a dodge in the programming. Since DHTML elements such as <SPAN> and <DIV> can't be assigned a document source (SRC) in the same way as frames or Netscape layers, it's impossible to move the content of an insert directly from an external file into the target <SPAN> or <DIV>, However, you can store insert material on a subsidiary Web page, load that page into a frame, and then transfer the material from that frame into your main document sitting inside its own frame. If the frame that contains the insert is invisible, the reader will not see what is really going on, making this second method of stretchtext functionally identical to the simpler, all-in-one method.

What's this about invisible frames? You may not be aware that the visible dimensions of a frame are totally independent of its storage properties. In its simplest terms a frame is simply a memory buffer: you can put information into a frame even when it has a width of zero. So in this week's demo we define the frameset (on page index.html) thus:

    <frameset cols="100%,*">
    	<frame name="main" src="hidemo.htm">
    	<frame name="hidden" src="source0.htm">
    </frameset>
    

The asterisk or wildcard character (*) instructs the browser to give the second frame all the column width left over after the previous frame has been defined. Since the previous frame has 100% of the screen, the second frame has zero width; but it's still functional.

To trigger the stretchtext effect we once again use a simple span with an onClick handler:

    This paragraph contains an 
    <span onClick="stretcher(1)" style="color: 990000">
    active link</span>
    that triggers a stretchtext transformation upon the paragraph.
    

As in last week's demo, the handler calls a JavaScript function and passes a single parameter. The function is a bit more complicated than last week's:

    function stretcher(which)
    {
    parent.frames['hidden'].document.location=("source"+which+".htm");
    if(which==1)
      {
        point1.innerHTML=parent.frames.hidden.insert.innerHTML;
      }
    }
    

The first line of the function changes the SRC assignment of the righthand, invisible frame ("hidden"), pulling in the external file that contains the insert material. Note that this happens outside the if condition; this allows us to avoid typing the frame-replacement instruction over again for each condition. (Though as you'll see below, you might want to use this more cumbersome method if you need finer control over the frame-loading process.)

The next instruction, within the if condition, copies the insert material from a designated <SPAN> on the source page into another <SPAN> on the display page. You may wonder why this instruction is framed by an if/then statement. Using the Document Object Model, it should be possible to refer to page elements by their index numbers within particular collections (for instance, spans[0]), much as we refer to form elements and frames in HTML-3 JavaScript. This approach would yield more elegant code, but it might also create limitations. What if you want a click on your first trigger to transform both the point1 span and a later point7 span? The more verbose if/then strategy seems more powerful, if less efficient.

Note that the property used for replacement in this week's demo is innerHTML, not innerText. This allows us to bring along further tags, formatting, and even trigger <SPAN>s in the insert text.

In the demo, the inserted material contains a trigger that resets the target <SPAN> point1 back to null content. Note that this transformation is effected by a JavaScript function installed on the main display page hidemo.htm, not on the external source page or on the frameset page index.html. All JavaScript transactions must take place on the main page or be routed through that page.

Should you use this multi-file method for your final project? You can probably use the single-file method as long as you pay close attention to your markup and remember which bits connect to which other bits in what ways. Multiple files can be confusing in their own ways. Even if you don't use this second method, though, you should know how it works in case you ever find yourself designing a really large or complex stretchtext.