Que Logo

Chapter 19

Script Example 5: Creating an eZine



In This Chapter

Start the Web-Presses!


By now, you may be thinking to yourself, "This author stuff doesn't seem that difficult. Heck, I could write my own book or publish a magazine and it'd be much better than what this guy's written." You may be right…and through the magic of the Web, you can give it a shot. And, publishing on the Web doesn't require a contract with a publisher, a fleet of editors, and tons of money-just you, your browser, and an idea.
Many have already started down the path of the eZine, an electronic, online version of the magazines you find at your favorite bookstore. Each day, another one is "published" through the Web (I've even heard there's a 'zine about chickens). If no one reads it but you, who cares? You've made your statement, presented your case, told your story, whatever you want to do.
But you are a JavaScripter… you want to be different. You want to stand out in the crowd as someone who knows his Web. That's what this example will do for you: a Do-It-Yourself JavaScript-Enabled eZine Framework (whew!).
At the same time, you'll get a chance to see a variety of JavaScript tricks all rolled into one power-collection of pages. A few Netscape HTML enhancements are thrown in that Navigator 2.0 supports (since you need Navigator 2.0 to view JavaScript, this is a pretty safe step).

JavaScript The eZine!


Any magazine, electronic or otherwise, consists of the following parts:
You can put these together using Netscape 2.0's <FRAME> tag. The <FRAME> tag allows you to break the browser's display area into subsections (each separated by a frame), and display a different HTML document in each frame. Since a picture is worth a thousand words, here's what our eZine will look like when you finish:

JavaScript: The eZine!


 
Now, let's tear this apart and look at each piece.

I've Been Framed!


The first thing you'll see is that the screen is divided into three areas. Each area is referred to as a frame. The frame that runs down the left side of the screen serves as your Table of Contents. Each link will load a particular article when clicked on. Articles that are loaded appear in the large frame on the right. When the user first loads the eZine, he is shown the cover page that you see in the figure. Finally, the third frame is a "help window," and you'll look at that more closely later.
So, the first thing you need is an HTML document that sets up your frames. This is the document that the user would load to read your eZine. By convention, the "main" or "primary" HTML document in a directory is called index.html, and you want to stick with convention. Here's your index.html:

<!- index.html: The "driver" of our eZine ->
<HTML>

<HEAD>
<TITLE>JavaScript: The eZine!</TITLE>
</HEAD>

<FRAMESET COLS="90,*">
 <FRAME SRC="buttons.html" NORESIZE NAME="Buttons" BORDER=1 SCROLLING=NO>
 <FRAMESET ROWS="*,60">
 <FRAME SRC="coverpage.html" NORESIZE NAME="Main" SCROLLING=AUTO>
 <FRAME SRC="helpwindow.html" NORESIZE NAME="Help" SCROLLING=NO>
 </FRAMESET>
</FRAMESET>

<NOFRAMES>
<BODY BGCOLOR=#FFFFFF>

<CENTER><H1>JavaScript: The eZine!</H1></CENTER>

<HR>

Since this is an eZine about JavaScript, you really ought to get
a browser that supports it. Why not check out
<A HREF="http://home.netscape.com/">Netscape Navigator 2.0</A>?

<HR>

Send your comments to the <A HREF="mailto: ">Editor</A>.

</BODY>
</NOFRAMES>
</HTML>

The <NOFRAMES> tag is basically a wrapper for what you want to display to people who don't have a frames-enabled browser. In this case, you gently urge people to get a newer browser and, since you're also using JavaScript, I suggest Navigator 2.0.
A collection (or set) of frames is defined with the <FRAMESET> tag. <FRAMESET> has two attributes, ROWS and COLS, which allow us to define the width of the various frames we want. In our example:

<FRAMESET COLS="90,*">
 <FRAME SRC="buttons.html" NORESIZE NAME="Buttons" BORDER=1 SCROLLING=NO>
 <FRAMESET ROWS="*,60">
 <FRAME SRC="coverpage.html" NORESIZE NAME="Main" SCROLLING=AUTO>
 <FRAME SRC="helpwindow.html" NORESIZE NAME="Help" SCROLLING=NO>
 </FRAMESET>
</FRAMESET>

a <FRAMESET> is nested inside another <FRAMESET>. You can do this as deep (as many nests) as you want, but don't get carried away with it (you can create frames too small to display much of anything). Another way to look at your collection of frames is thusly:
My frames consist of two columns. The left column is 90 pixels wide, the right column is whatever's left of the screen width. The left column will be called "buttons" and will load "buttons.html". The right column is further divided into two frames, the bottom one 60 pixels tall, the top one whatever's left. Call the top frame "Main" and load "coverpage.html", while the bottom one will be "Help" and will load "helpwindow.htm".

By using the "*" value for the frame width, you tell the browser to make that frame whatever width is left after the other fixed widths have been computed.
Also, notice the <FRAME> attributes NORESIZE and SCROLLING. NORESIZE tells the browser not to let the user grab the frame and drag (resize) it. Without this attribute, moving the mouse over the frame edge will cause the mouse cursor to change to the familiar Windows resize cursor. If the user were to grab the frame by clicking on it, the frame could be moved.
The SCROLLING attribute controls whether a scroll bar will be displayed. By default, the value of SCROLLING is AUTO, meaning that a scroll bar will appear only if the page is bigger than the frame. In this case, you don't want scrolling on the help window or the table of contents, so you set SCROLLING=NO. Setting SCROLLING=YES would make a scroll bar always appear, even if the document was smaller than the frame.
As you can see, the <FRAMES> tag doesn't really display any text. It simply defines the frames and indicates which documents should be loaded into which frames.
Now, let's move through each piece of the eZine. We'll start with the more interesting one: the help window.

Help Me!


You're probably wondering about that short frame at the bottom of the screen_the one with the words "Article #3" in it. That's the help window, and it is powered by JavaScript. As the user moves the mouse over the table of contents, the text in the help window will change to relate to whatever the user is pointing to. With the help window, you can display a one-line description of each link in the table of contents.
The help window is a simple FORM with one field: a text field named "helpmsg" that will receive information sent to it from the table of contents. Here's the HTML file:

<!- helpwindow.html: The eZine help window ->
<HTML>

<HEAD>
<TITLE>JavaScript: The eZine!</TITLE>
</HEAD>

<BODY BGCOLOR=#FFFFFF>

<CENTER>
 <FORM>
 <INPUT TYPE="text" NAME="helpmsg" SIZE=60>
 </FORM>
</CENTER>


</BODY>
</HTML>

Nothing fancy, but with the addition of the table of contents buttons, it produces a very nice effect.
In the previous programs, all of the frames have the same "title," as defined by the <TITLE> tag. However, recall just what the purpose of the HTML "title" is. It doesn't appear anywhere within the document itself. The title pops up in two places: the upper border of the browser window, and the bookmark list. We've used the same title, "JavaScript: The eZine!" for each frame because it is appropriate for either the browser windowframe or bookmark.
You'll see the table of contents now.

The Table of Contents


The table of contents (the frame on the left) is your control center. As the user passes the mouse over one of the links, a line of text describing that link is sent to the help window frame below.
How is this done? First, remember that the helpwindow.html file contains a form with one field, helpmsg. Forms are accessible from within JavaScript, and with JavaScript, the data in form fields can be changed. Also, remember that since each frame is a document-and each document is attached to the main window-you can "reach" from one frame into another and do something to it.
First, create an array of help strings to display:

function MakeArray(size) 
{
 this.length = size;
 for(i = 1; i <= size; i++) 
 {
 this[i] = '';
 }

 return this;
}


msg = new MakeArray(7);

msg['story1'] = 'Article #1';
msg['story2'] = 'Article #2';
msg['story3'] = 'Article #3';
msg['story4'] = 'Article #4';
msg['story5'] = 'Article #5';
msg['index'] = 'Return to the cover page';
msg['expand'] = 'Remove the button bar and help window';

This uses your familiar MakeArray() function. It also creates your message array, msg[] outside a JavaScript function, making the array "visible" to any other JavaScript functions.
Now that you have the array, you need to display it. What you want to do is create a special link on the page that handles the onMouseOver event:

<A HREF="story1.html" 
 TARGET="Main"
 ONMOUSEOVER="message('story1', this.href); return true;">
Story 1</A>

The onMouseOver event handler simply calls our message() function and passes an "ID tag" (the index into the msg[] array) and the HREF associated with this link. Also, notice that our TARGET is "Main". This means that the HREF that will be loaded (a story document, in this case) will be loaded into the frame named "Main" (the large frame on the right of the screen).
The message() function looks like this:

clearid = 0;

function message(button,url) 
{
 if(clearid)
 {
 clearTimeout(clearid);
 }

 window.parent.frames['Help'].document.forms[0].helpmsg.value = msg[button];
 self.status = url;
 clearid = 
setTimeout("window.parent.frames['Help'].document.forms[0].helpmsg.value = ''", 5000);
}

That rather long window.parent.frames['Help']... line is what does the magic. It loads the selected msg[] text into the value property of the helpmsg field in the form of the helpwindow frame. That's a long-winded way of saying that it copies a string somewhere else on the page-but it works!
Putting this all together, here's the table of contents document, buttons.html:

<!- buttons.html: eZine table of contents ->
<HTML>

<HEAD>

<TITLE>JavaScript: The eZine!</TITLE>

<SCRIPT LANGUAGE="LiveScript">
<!- Hide from non-JavaScript browsers

function MakeArray(size) 
{
 this.length = size;
 for(i = 1; i <= size; i++) 
 {
 this[i] = '';
 }

 return this;
}


msg = new MakeArray(7);

msg['story1'] = 'Article #1';
msg['story2'] = 'Article #2';
msg['story3'] = 'Article #3';
msg['story4'] = 'Article #4';
msg['story5'] = 'Article #5';
msg['index'] = 'Return to the cover page';
msg['expand'] = 'Remove the button bar and help window';

clearid = 0;

function message(button,url) 
{
 if(clearid)
 {
 clearTimeout(clearid);
 }

 window.parent.frames['Help'].document.forms[0].helpmsg.value = msg[button];
 self.status = url;
 clearid = 
setTimeout("window.parent.frames['Help'].document.forms[0].helpmsg.value = ''", 5000);
}

//->
</SCRIPT>
</HEAD>

<BODY BGCOLOR=#FFFFFF>

<CENTER>

<FONT SIZE=1>
<STRONG>CONTENTS</STRONG>
<FONT SIZE=>

<HR SIZE=4 ALIGN=CENTER>

<A HREF="story1.html" 
 TARGET="Main"
 ONMOUSEOVER="message('story1', this.href); return true;">
Story 1</A>

<HR  WIDTH=25% ALIGN=CENTER>

<A HREF="story2.html" 
 TARGET="Main"
 ONMOUSEOVER="message('story2', this.href); return true;">
Story 2</A>

<HR  WIDTH=25% ALIGN=CENTER>

<A HREF="story3.html" 
 TARGET="Main"
 ONMOUSEOVER="message('story3', this.href); return true;">
Story 3</A>

<HR  WIDTH=25% ALIGN=CENTER>

<A HREF="story4.html" 
 TARGET="Main"
 ONMOUSEOVER="message('story4', this.href); return true;">
Story 4</A>

<HR  WIDTH=25% ALIGN=CENTER>

<A HREF="story5.html" 
 TARGET="Main"
 ONMOUSEOVER="message('story5', this.href); return true;">
Story 5</A>

<HR  WIDTH=25% ALIGN=CENTER>

<A HREF="index.html" 
 TARGET="_top"
 ONMOUSEOVER="message('index', this.href); return true;">
Index</A>

<HR  WIDTH=25% ALIGN=CENTER>

<A HREF="" 
 TARGET="_top"
 ONMOUSEOVER="message('expand', this.href); return true;"
 ONCLICK="{
 alert('You can restore the button bar by\npressing the BACK button.');
 this.href = window.parent.frames['Main'].document.location;}">
Expand</A>

<HR SIZE=4 ALIGN=CENTER>

<SCRIPT LANGUAGE="JavaScript">
<!- Hide from non-Javascript browsers

function DisplayDate(dateString)
{
 d = new Date(dateString);

 return "" + (d.getMonth() + 1) + "/" + d.getDate() + "/" + d.getYear();
}

document.write("<FONT >");
document.write("<B>" + DisplayDate(document.lastModified) + "</B>");
document.write("<P><FONT SIZE=>");

//->
</SCRIPT>


</CENTER>

</BODY>
</HTML>

Three final things to look at before moving on. First, look at the line:

<A HREF="index.html" 
 TARGET="_top"
 ONMOUSEOVER="message('index', this.href); return true;">
Index</A>

Remember that assigning _top as a target effectively reloads everything, not just a particular frame. This is important to use, especially when you're linking to a page outside your eZine_one that doesn't support frames. Otherwise, your browser will try to load the new page into whatever frame you've specified (and if you don't specify a target, the current frame is assumed). Try to load your entire home page into a window the width of the table of contents and you'll understand why this is a problem.
Second, check out the line:

<A HREF="" 
 TARGET="_top"
 ONMOUSEOVER="message('expand', this.href); return true;"
 ONCLICK="{
 alert('You can restore the button bar by\npressing the BACK button.');
 this.href = window.parent.frames['Main'].document.location;}">
Expand</A>

This does a _top load like the Index link, but it also hooks the onClick event handler to do something else very nifty. Before the URL is loaded, the HREF attribute is set to whatever the HREF is of the document currently displayed in the "Main" window. Think of it as a short way of saying, "Take whatever is currently loaded in 'Main' and reload it… filling the full screen." Because this eliminates the frame containing the button bar, the addition of the alert() method provides an easy reminder to the user of how to get the bar back. See the figure on the next page.
Finally, the date displayed at the bottom of the table of contents has some properties of its own. It uses the lastModified property of the document object to retrieve the date that you last changed the document. With a little modification, it displays this date at the bottom of the screen. This is an easy way of showing the user when the eZine was created or changed. It also shows off one other important JavaScript feature: you can use the SCRIPT tag more than once in a document.

Clicking on Expand generates a reminder.

Stories


Okay, you've seen the tough stuff_you're almost done. The story1.html through story2.html files are nothing more than regular HTML files:

<!- story1.html: an example eZine story ->
<HTML>

<TITLE>JavaScript: The eZine!</TITLE>

<BODY BGCOLOR=#FFFFFF>

<H1>Article 1</H1>

<HR>

Article 1 goes here.

</BODY>
</HTML>

that you can embellish to your heart's content. Just remember that if you add any links to pages outside your eZine, you'll want to add the TARGET="_top" attribute to the <A> tag; otherwise, things will start to look very strange.
The last part is the first part your readers will see: the cover page.

Cover (Page) Me with JavaScript


This example cover page isn't incredibly fancy, but it does have a nice touch:

<!- coverpage.html: eZine coverpage ->
<HTML>

<TITLE>JavaScript: The eZine!</TITLE>

<BODY BGCOLOR=#FFFFFF>

<H1><CENTER>JavaScript: The eZine!</CENTER></H1>

<HR>

<SCRIPT LANGUAGE="JavaScript">
<!- Hide from non-Javascript browsers

d = new Date();
hour = d.getHours();

if(hour < 5)
{
 document.write("Doing a little late-night surfing, eh?");
}
else
if(hour < 6)
{
 document.write("Up early, I see! Do you have your coffee?");
}
else
if(hour < 12)
{
 document.write("Good morning!");
}
else
if(hour < 18)
{
 document.write("Good afternoon!");
}
else
{
 document.write("Good evening!");
}

document.write("<P>");

//->
</SCRIPT>

So, you want to do the JavaJive ... but you don't want to program?

<P>

Well ... you've come to the right place. Check out the articles
here and <B>you too</B> can become a 
<B><I>PowerJavaScripter</I></B>!

<HR>

<FONT >
<I>Send your comments to the <A HREF="mailto: ">Editor</A>.</I>
<FONT SIZE=>

</BODY>
</HTML>

Notice the JavaScript script in the <BODY>? It doesn't have any functions, just statements. This means that the statements will be executed after the page loads (and before it is displayed), even though the user hasn't clicked on anything. In this example, it uses the Date object to figure out what time of day the user is reading your eZine. Depending on the hour, it displays a different message.
There… you have all the pieces for a basic eZine. Now, get out there and publish!

The Least You Need To Know


This chapter took a final look at JavaScript by pulling different features together into a real application: an eZine. You learned how to:

Previous Chapter

Next Chapter


Beginning of ChapterTable of ContentsBook Home PageQue Home Page


For comments or technical support for our books and software, select Talk to Us.
To order books, call us at 800-716-0044 or 317-228-4366.

© 1996, QUE Corporation, an imprint of Macmillan Publishing USA, a Simon & Schuster Company.