Michael Yu's Civic Car viewing program provides you with a good example of how to combine frames with JavaScript. It's located at
http://www-leland.stanford.edu/~guanyuan/public/car/car.html
The premise behind the program is simple: In one frame, a view of a Honda Civic is displayed. In the other frame, the user has four directional controls to rotate the view in steps in any direction: up, down, left, or right.
In achieving this, Yu has made use of a simple file naming scheme, the windows.location property, and the frames array.
The program in Listing W3.1 produces results similar to those in Figures W3.1 and W3.2.
Parent frameset:
<HTML> <head> <title> Car View 3D</title> </head> <FRAMESET ROWS="18%, 72%, 10%"> <FRAME SRC="head.html" NAME="head" TARGET="head" SCROLLING="no"> <FRAMESET COLS="68%, 32%"> <FRAME NAME="left" SRC="left.html" NORESIZE> <FRAME NAME="right" SRC="right.html" NORESIZE> </FRAMESET> <FRAME SRC="tail.html" NAME="tail" SCROLLING="no"> </FRAMESET> <noframes> <h2 align="center">Sorry, Netscape 2.0b3 (Beta 3) required.</h2> </noframes> </BODY></HTML>
The file right.html:
<html> <title>control pad</title> <BODY BGCOLOR="ffffff" LINK="#0000FF" ALINK="#D9D919" VLINK="#871F78"> <form method="post"> <center> <br> <h3> Rotation<br>Control Panel</h3> <br> You can use the following control panel to rotate the civic car. <br> <div align="center"> <table border=0 cellspacing=0 cellpadding=0> <tr> <td></td> <td><input type="button" name="upmiddle" value="U" onclick="up()"></td> <td></td> </tr> <tr> <td><input type="button" name="middleleft" value="L" onclick="left()"></td> <td></td> <td><input type="button" name="middleright" value="R" onclick="right()"></td> </tr> <tr> <td></td> <td><input type="button" name="downmiddle" value="D" onclick="down()"> <td></td> </tr> </table> </div> <br> <a href="http://www-leland.stanford.edu/~guanyuan/michael.html" target="_top"> <img src="cycleimages.gif"> </a> </center> </form> <script language="LiveScript"> var ud=0; var lr=0; var chars="012345678"; function up(){ getcar(1,0); return 0; } function down(){ getcar(-1,0); return 0; } function left(){ getcar(0,1); return 0; } function right(){ getcar(0,-1); return 0; } function getcar( myud, mylr){ ud=ud+myud; lr=lr+mylr; if (lr == 8) { lr=0;}; if (lr == -1) { lr=7;}; if (ud == 3) { ud=1; lr=4+lr;}; if (ud == -1) { ud=1; lr=lr+4;}; if (lr > 7) { lr=lr-8;}; parent.frames[1].location="http://www-leland.stanford.edu/~guanyuan/public/car/car"+chars.substring(ud,ud+1)+"_"+chars.substring(lr,lr+1)+".html"; return 0; } </script> </body> </html>
Output
The Civic Car Viewer uses two main working frames across the center of the window: The car is displayed on the left, and the rotation controls are in the right hand frame.
Figure W3.1. Michael's Civic Car Viewer provides interactivity between frames.
Figure W3.2. The user selects a rotation control on the right, and the image on the left updates.
End of Output
Analysis
Although the Civic Car Viewer may seem simple at first glance, it provides a good example of how to build easy-to-use programs using multiple frames. It is interesting to note that the program does not follow Netscape's recommendation of placing function definitions in the header of the HTML file. This means it is possible that a user could press one of the four buttons before a function has been evaluated.
All the image files are named carA_B.html where A and B are integers. A represents the up-down axis and can have values from 1 to 3, and B represents the left-right axis
and can have values from 0 to 7.
The script uses three global variables:
var ud=0; var lr=0; var chars="012345678";
ud and lr are used to keep track of the current viewing angle of the car. The variable chars is used to build the URL for a new view, as you will see later.
The primary function is getcar(). This function accepts two arguments myud and mylr, which represent changes to the values of ud and lr:
ud=ud+myud; lr=lr+mylr;
Once the changes to the values are made, a series of if statements are used to check if the new value is outside the acceptable range for each variable; if it is, the command block of the if
statement wraps it around to the other end of the range. For instance, if lr is 8 it becomes 0:
if (lr == 8) { lr=0;}; if (lr == -1) { lr=7;}; if (ud == 3) { ud=1; lr=4+lr;}; if (ud == -1) { ud=1; lr=lr+4;}; if (lr > 7) { lr=lr-8;};
Once this has been done, the function is ready to open the new view in the left frame using
parent.frames[1].location="http://www-leland.stanford.edu/~guanyuan/public/car/car" +chars.substring(ud,ud+1)+"_"+chars.substring(lr,lr+1)+".html";
The command uses parent to look at the parent frameset and the frames array to explicitly choose the desired frame. It then sets the location property to the new URL.
The actual filename is built up with the portion of the URL expression which reads:
car"+chars.substring(ud,ud+1)+"_"+chars.substring(lr,lr+1)+".html"
The substring() method is used to select single digits from the chars variable based on the values of ud and lr respectively.
Each of the four buttons in the form calls one of four functions: up(), down(), left(), or right(). These functions all work in the same way. They call getcar() with appropriate arguments based on the direction and then they return a value 0. The value
returned by the function is incidental because the value is never used anywhere in the script.
Michael Yu's Civic Car Viewer is a concrete example of how combining frames and JavaScript makes it possible to create interactive applications. By taking advantage of frames to build sophisticated interfaces and combining that with JavaScript's ability to generate dynamic URLs, it is possible to extend the simple Web metaphor into something more diverse and powerful.