Приглашаем посетить
Дружинин (druzhinin.lit-info.ru)

8.1 Controlling frames I

Table of Contents

Previous Next

8.1 Controlling frames I

8.1.1 A classic dynamic menu with swapping frames

One of the advantages of using frames is that individual pages can be organized (or networked together) to form a larger and more complex application. A typical application (see Chapter 1, ex01-17.htm) is to divide the screen into two frames (usually left and right) or more and build a menu (or navigation bar) system. The left frame, for example, stores the menu items. When one of the menu items is pressed, a corresponding page is sent to the right frame. Many organizations use this technique to introduce their departments and a lot of businesses advertise their products in the same way on the Web. This is a static XHTML menu technique and one restriction is that you don't know much about the information of a selected menu item. In this section, we will show you how to write a Web page with a navigation bar. This page has a master frame page as given in ex08-01.htm.



Example: ex08-01.htm - Swapping Frames

 1: <?xml version="1.0" encoding="UTF8"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
 3:      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title>Swapping Frames  ex0801.htm </title></head>
 6: <frameset cols="35%,*">
 7:   <frame src="left01a.htm" id="left_f" name="left_f" />
 8:   <frame src="right01a.htm" id="right_f" name="right_f" />
 9: </frameset>
10: </html>

This frame page divides the screen into left and right frames with the preloaded pages left01a.htm and right01a.htm respectively. The left frame has an identity left_f (line 7). This identity can be used to access the frame later. The page left01a.htm is listed as follows:



Example: left01a.htm - The Left Frame For ex08-01.htm

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> File: left01a.htm </title>
 6:  <style> .mSt{font-family:arial;font-size:16pt;
 7:           font-weight:bold;color:#ffff00}</style>
 8:  <script>
 9:   function switchFrame(varV)
10:   {
11:     parent.left_f.location.href="left01"+varV+".htm"
12:     parent.right_f.location.href="right01"+varV+".htm"
13:   }
14:  </script>
15: </head>
16:
17: <body style="background:#000088;text-align:center">
18:  <div class="mSt" style="color:#00ffff">Company I<br /><br /></div>
19:  <span class="mSt" style="color:#ff00ff">Page A</span><br />
20:  <a href="javascript:switchFrame('b')" class="mSt">Page B</a><br />
21:  <a href="javascript:switchFrame('c')" class="mSt">Page C</a>
22: </body>
23: </html>

This page contains three items, namely, "Page A," "Page B," and "Page C" (see lines 1921). The items "Page B" and "Page C" are hyperlinks. For example, when the underlined text "Page B" is clicked, the JavaScript function switchFrame('b') is called (see line 20). The argument b is substituted into variable varV in lines 913 and the statements



parent.left_f.location.href="left01"+varV+".htm"
parent.right_f.location.href="right01"+varV+".htm"

send the pages left01b.htm and right01b.htm to the left and right frames respectively. The file right01a.htm in the right frame is a Web page with a simple ECMAScript function.



Example: right01a.htm - The Right Frame For ex08-01.htm

 1: <?xml version="1.0" encoding="iso-8859-1"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title>File right01a.htm </title>
 6:  <style>
 7:   h3{font-family:arial;font-size:18pt;font-weight:bold}
 8:   .mSt{font-family:arial;font-size:16pt;font-weight:bold;color:#ffff00}
 9:  </style>
10:  <script>
11:   function switchFrame(varV)
12:   {
13:     parent.left_f.location.href="left01"+varV+".htm"
14:     parent.right_f.location.href="right01"+varV+".htm"
15:   }
16:  </script>
17: </head>
18:
19: <body style="background:#000088;text-align:center">
20:  <h3 style="color:#ffff00">Company I<br /><br /><br /></h3>
21:  <h3 style="color:#00ffff">This is Page A<br /><br /></h3>
22:  <br /><br /><br /><br />
23:
24: <div align="left" class="mSt" style="color:#ff00ff">A
25: <a href="javascript:switchFrame('b')" class="mSt">B</a>
26: <a href="javascript:switchFrame('c')" class="mSt">C</a>
27: </div>
28: </body>
29: </html>

The same swapping technique is employed in lines 2427 to control the changing frames from the footnote of the right page. Some of the frame swapping actions are captured in Figs 8.1 and 8.2.

Figure 8.1. Activate Page A

graphics/08fig01.jpg


Figure 8.2. Activate Page B

graphics/08fig02.jpg


This is a classic example and works even on some old browsers. The main drawback of this technique is that it contains too many files. For instance, for this example to work, you need to have the following files:

ex08-01.htm (Master frame file)

left01a.htm

right01a.htm

left01b.htm

right01b.htm

left01c.htm

right01c.htm


In this case, one master frame file and six child frame pages are needed. You can imagine that the administrative work will soon become a nightmare if you have dozens of menu items. To solve this problem, we consider using variables in the master frame page.

8.1.2 Another approach to dynamic menu

Since the master frame file is always available, you can also store some variables to represent the status of each menu item. Child frames can access these variables and values later. The master frame file is listed in ex08-02.htm.



Example: ex08-02.htm - Another Approach To Swapping Frames

 1: <?xml version="1.0" encoding="UTF-8"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
 3:      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> Another Swapping Frames  ex0802.htm </title></head>
 6: <script>
 7:   paDisable=-1
 8:   pbDisable=0
 9:   pcDisable=0
10: </script>
11: <frameset cols="35%,*">
12:   <frame src="left02.htm" id="left_f" name="left_f" />
13:   <frame src="right02a.htm" id="right_f" name="right_f" />
14: </frameset>
15: </html>

This page has three new variables, paDisable, pbDisable, and pcDisable (lines 79). They represent the on and off status of the corresponding "Page A," "Page B," and "Page C" menu items in the left frame. Initially, we want the "Page A" item disabled (paDisable=-1) when the page is loaded. In this example, only one left frame, left02.htm, is used to hold and control the menu (line 12). Consider the left page:



Example: left02.htm - The Left Frame For ex08-02.htm

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title>File left02a.htm: </title>
 6: <style> .mSt{font-family:arial;font-size:16pt;border:0;
 7:           background:#000088;font-weight:bold;color:#ffff00}
 8: </style>
 9:  <script src="frame01.js"></script>
10: </head>
11:
12: <body style="background:#000088;text-align:center">
13:  <div class="mSt" style="color:#00ffff">Company I<br /><br /></div>
14:  <input type="button" id="pa" onclick="resetD('a');switchFrame('a')"
15:    onmouseover="this.style.background='#008800'" value="Page A"
16:    onmouseout="this.style.background='#000088'" class="mSt" /><br />
17:  <input type="button" id="pb" onclick="resetD('b');switchFrame('b')"
18:    onmouseover="this.style.background='#008800'" value="Page B"
19:    onmouseout="this.style.background='#000088'" class="mSt" /><br />
20:  <input type="button" id="pc" onclick="resetD('c');switchFrame('c')"
21:    onmouseover="this.style.background='#008800'" value="Page C"
22:    onmouseout="this.style.background='#000088'" class="mSt" /><br />
23:
24:  <script> initialV() </script>
25: </body>
26: </html>

This left page is a controller and uses an external program file frame01.js to perform the dynamic frame swapping. The program file contains three functions (see line 14):



resetD("a") switchFrame("a") initialV()

The switchFrame('a') function is used to send a page (e.g., Page A in this case) to the right frame. The reset function resetD('a') sets the parent variable paDisable to be true. The initialization function initialV() in line 24 initializes all variables when this page is loaded. It also sets the status and changes the color of disabled items. Once the disable flag of an item is set, there will be no action related to that item. Also in this example, we use buttons with no borders to simulate the plain text situations. Mouse-over and mouse-out events are used to highlight menu items. When the user presses the menu item, "Page A" in line 14, the script function resetD('a') is called to disable the menu and to switch the frames accordingly. These changes will take effect only after the initialization function initialV() is called. The listing of the ECMAScript is shown below:



Example: frame01.js - The ECMAScript File For left02.htm

 1: function switchFrame(varV)
 2: {
 3:   parent.left_f.location.href="left02.htm"
 4:   parent.right_f.location.href="right02"+varV+".htm"
 5: }
 6: function resetD(varL)
 7: {
 8:  parent.paDisable=0
 9:  parent.pbDisable=0
10:  parent.pcDisable=0
11:  if (varL =='a') parent.paDisable=-1
12:  if (varL =='b') parent.pbDisable=-1
13:  if (varL =='c') parent.pcDisable=-1
14: }
15: function initialV()
16: {
17: document.getElementById("pa").disabled=parent.paDisable;
18: document.getElementById("pb").disabled=parent.pbDisable;
19: document.getElementById("pc").disabled=parent.pcDisable;
20: if (parent.paDisable)document.getElementById("pa").style.color="#aaaaaa"
21: if (parent.pbDisable)document.getElementById("pb").style.color="#aaaaaa"
22: if (parent.pcDisable)document.getElementById("pc").style.color="#aaaaaa"
23: }

Line 4 illustrates the string concatenation capability of ECMAScript in the function switchFrame(). In practice, you may want to substitute the actual names of the frames into a function argument. Some actions and screen shots are captured in Figs 8.3 and 8.4.

Figure 8.3. Mouse over Page B

graphics/08fig03.jpg


Figure 8.4. Disable the item "Page B" on the left

graphics/08fig04.jpg


Similarly the right page (e.g., right02a.htm) for ex08-02.htm also uses the same program file frame01.js to control and swap the frames. Consider the right page:



Example: right02a.htm - The Right Frame For ex08-02.htm

 1: <?xml version="1.0" encoding="iso-88591"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> File right02a.htm </title>
 6:  <style>
 7:   h3{font-family:arial;font-size:18pt;font-weight:bold}
 8:   .mSt{font-family:arial;font-size:16pt;border:0;
 9:           background:#000088;font-weight:bold;color:#ffff00}
10:  </style>
11:  <script src="frame01.js"></script>
12: </head>
13: <body style="background:#000088;text-align:center">
14:  <h3 style="color:#ffff00">Company I<br /><br /><br /></h3>
15:  <h3 style="color:#00ffff">This is Page A<br /><br /></h3>
16:   <br /><br /><br /><br />
17:
18: <div align="left" class="mSt" style="color:#aaaaaa">
19:  <input type="button" value="A"
20:    disabled class="mSt" style="color:#aaaaaa" />
21:  <input type="button" value="B"
22:    onclick="resetD('b');switchFrame('b')" class="mSt" />
23:  <input type="button" value="C"
24:    onclick="resetD('c');switchFrame('c')" class="mSt" />
25: </div>
26: </body>
27: </html>

Again, three buttons with no borders are used in this page to simulate the plain text. When the visitor clicks one of these buttons, the same swapping technique is employed to send the corresponding frame to the right hand side (see lines 1924). The central idea is to manipulate the variables in the parent frame.

Now, it's time to consider some housekeeping of frames. First, if you don't want your page to appear or be included inside a frame of someone's Web site, you may want to develop a page that cannot be framed.

8.1.3 A page that cannot be framed

To develop such a page is easy. You can first detect the top level of the window and then compare it to the current page (or window). If they are not equal, you can set the top level of the window as the current page. Suppose we have a master frame page as shown in ex08-03.htm.



Example: ex08-03.htm - A Page that Cannot Be Framed

 1: <?xml version="1.0" encoding="UTF-8"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
 3:      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head>
 6:   <title>ex0803.htm </title>
 7: </head>
 8: <frameset rows="50%,*">
 9:   <frame src="upper.htm"   id="upper_f"   name="upper_f" />
10:   <frame src="lower.htm"   id="lower_f"   name="lower_f" />
11: </frameset>
12: </html>

This master frame page calls two pages, upper.htm and lower.htm. These are allocated to the upper and lower parts of the browser screen respectively. However, if the lower page contains the statements as in lines 89 of lower.htm, the calling process will be interrupted.



Example: lower.htm - The Bottom Frame For ex08-03.htm
 1: <?xml version="1.0" encoding="UTF-8"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title>File: lower.htm</title></head>
 6: <style>h2{font-family:arial;font-size:18pt;color:#ffff00}</style>
 7: <script>
 8:   if (window.top.location != window.self.location)
 9:        window.top.location = window.self.location
10: </script>
11: <body style="background:#000088;text-align:center">
12: <h2>This Page Cannot Be Framed<br />File: lower.htm</h2>
13: </body>
14: </html>

When this page is called, the script statement in line 8 detects the top level of the window and compares it to the current window level. If they are not the same, the statement in line 9 will assign the top level as the current window. As a result, this lower.htm page will replace the master frame and therefore we have only one page on the browser screen (see Fig. 8.5).

Figure 8.5. ex08-03.htm

graphics/08fig05.jpg


In practice, this technique provides a way to prevent a page accidentally, or deliberately, being loaded into a frame. If you want, you can add lines 710 to your master frame pages to ensure that they are always on the top window level. Another housekeeping technique on frames is to make sure that a page is always enclosed inside a frame.

8.1.4 Keeping frames in order

For a successful frame application, the ordering, presentation, and interrelationship between the use of frames and Web pages are vital. In many cases, for instance, you don't want a frame page that is out of control and is not inside a frame. To keep frames under control, the same window location techniques are used. Consider a master frame page ex08-04.htm with the code fragment



Listing: ex08-01.txt - Code Fragment Of ex08-04.htm

1: <frameset cols="45%,*">
2:  <frame src="left04.htm" id="left_f" name="left_f" />
3: <frame src="right04.htm" id="right_f" name="right_f" />
4: </frameset>

If you want the two child frame pages (left04.htm and right04.htm) always under the master frame, you can add a small piece of script code as listed in left04.htm.



Example: left04.htm - The Left Frame For ex08-04.htm

 1: <?xml version="1.0" encoding="UTF-8"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
 3:      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title>File: left04.htm</title></head>
 6: <style>h2{font-family:arial;font-size:18pt;color:#ffff00}</style>
 7: <script>
 8:   if (window.top.location == window.self.location)
 9:       window.top.location.href ="ex0804.htm"
10: </script>
11: <body style="background:#000088;text-align:center">
12: <h2>This Left Page Must Be <br />In a Frame<br />File: left04.htm</h2>
13: </body>
14: </html>

The script statements in lines 89 are simple. First, we detect the window level. If the current window is the top, we assign our master frame page as the top level. This will load all child frames and pages automatically (see Fig. 8.6).

Figure 8.6. ex08-04.htm

graphics/08fig06.jpg


With these housekeeping techniques, we're now ready to consider applications with more dynamic frames.

    Table of Contents

    Previous Next