Section 9.3. Frames and Location


9.3. Frames and Location

I must admit up front that I'm not fond of frames. Yes, they are extremely useful, and still a terrific way to manage applications in which an action in the left window (or top window) can trigger a change in the right (or bottom). Each can then scroll separately, without any effort on our part.

However, too many companies had (or still have) a habit of opening up other web sites into frames, which basically wrapped the other site's content in their own environment. Most of us didn't care for this. Luckily, thanks to JavaScript, we can defeat this technique using a second window object, location.

The location object stores information about the current location and provides a small set of routines to load a new document or replace whichever document is currently loaded.

The frame object has a few properties and methods, and is primarily a subset of the window object. This makes sense considering that each is a window, in miniature. Among the objects supported are frames, name, length, parent, and self. The methods supported are blur, focus, setInterval, clearInterval, setTimeout, and clearTimeout. Of these, the ones new to this example are parent, which would be the parent frameset, length for length of frame, and name, which is the frame name.

The name and parent are particularly important for cross-frame communication. A parent frameset can access each child frame through its name (or through the frames array using the number of the object as an index); each frame can access the frameset tHRough the generic term, parent. Siblings can access each other by accessing parent and then the name of the sibling.

In Example 9-5, a frameset with two frames is loaded. The two frames are known as framea and frameb.

Example 9-5. Frameset loading two frames

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Frames</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <frameset cols="300,*"> <frame name="framea" src="/books/4/327/1/html/2/framea.htm" /> <frame name="frameb" src="/books/4/327/1/html/2/frameb.htm" /> </frameset> </html>

Into framea, a document, framea.htm, is loaded. It has one link that, when pressed, accesses its sibling through its parent and changes the frame location to itself. The page for this is shown in Example 9-6. The second frame document, frameb.htm, has the exact same page, except it steals framea's spot for itself.

Example 9-6. Each frame loading itself

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <h1>Frame A</h1> <p><a href="" onclick="parent.frameb.location.replace" ('http://learningjavascript.info/framea.htm')">Change sibling</a></p> </body> </html>

The individual frame pages load themselves using the location's replace method.

9.3.1. More On Location

The location object's properties are all related to the page location. You've seen one of its functions, replace, used to replace the page for one of the frames. Another is reload, which instructs the browser to refresh the document. It also has properties associated with the page location, including the domain, port, and protocol, that are used with location; these are given in Table 9-2.

Table 9-2. Location object properties
PropertyPurpose
hash

For URLS of the format http://some.com/somepage#somehash, this property contains "somehash"the value after the hash mark
host

Hostname (domain) and port of URL
hostname

The hostname (domain) only
href

The entire URL (read and write)
pathname

The pathname that follows the domain
port

The URL port
protocol

The protocol used with the URL, such as "http"
search

The query string, if one exists, that derives the page. This includes anything following the first question mark of the URL
target

If given, the URL's target name


Accessing a URL such as the following:

http://learningjavascript.info/ch09-01.htm?a=1

results in the following property values:

host/hostname: learningjavascript.info protocol: http: search: ?a=1 href: http://learningjavascript.info/ch09-01.htm?a=1

Returning to the initial issue about frames, and your pages being loaded into them without your permission, use the location objectin conjunction with a few other odds and endsto defeat this technique.

Example 9-7 shows another frameset; this one loads frames named frameone and frametwo.

Example 9-7. Loading two frames

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>Frames</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <frameset cols="300,*"> <frame name="frameone" src="/books/4/327/1/html/2/frame1.htm" /> <frame name="frametwo" src="/books/4/327/1/html/2/frame2.htm" /> </frameset> </html>

Neither frame1.htm nor frame2.htm is of much interest. The frametwo page has a link to another page, called noway.htm, which has the interesting bits, repeated in Example 9-8.

Example 9-8. Preventing opening in frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> //<![CDATA[ if (self != top) { if (window.location.href.replace)         top.location.replace(self.location.href);     else         top.location.href=self.document.href; } //]]> </script> </head> <body> <h1>No Way</h1> </body> </html>

In the newly opened page, which normally opens into the frame, there's a script block that tests whether it is, itself, the top window. In framed windows, the frameset is the top window. In the code, if the window is not the top window (is loaded into a frame), it sets the top-window location href property to itselfeffectively bumping the frameset out of the way.

Simple and clean. However, you'll find few pages that frame-protect themselves nowadays. Frames just aren't as popular as they once were, and most people don't want to add anything unnecessarily to their pages.

Not all frames require a frameset parent. The iframe can be embedded in a page, rather than a frameset.

9.3.2. Remote Scripting with the iframe

Ajax achieved almost instant fame through its promotion of in-page client/server interaction. This is a process in which data can be submitted to a server and a page updated without having to reload the page. This was all shiny new, though the technology had been around for a few years.

Even before Ajax and its MS precursor, there were ways to implement remote-server functionality. One popular method was to use the HTML element, the iframe, and a concept of remote scripting.

The concept of using the iframe for remote scripting was introduced at the Apple Developer Network in an article written by Eric Costello; it is available at http://developer.apple.com/internet/webcontent/iframe.html.


Unlike regular frames, an iframe is actually embedded within a page. It can be given both height and width to be displayed, or it can be hidden by setting both to zero. It considers the page it's embedded in as its parent, and that's how it communicates with the higher-level page. Normally, it can be accessed by using the document's getElementById; you can also load content into it using the target attribute in a link.

In Example 9-9, an iframe is embedded in the page, with text about making a choice between the red pill or the blue. Each of these is a link, which will load the choice page into the iframe.

Example 9-9. Communicating with an embedded iFrame

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>iFrame</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <script type="text/javascript"> //<![CDATA[ function handleResponse(choice) {   var pick = frames["MyFrame"];   pick.document.writeln(choice); } //]]> </script> <iframe    name="MyFrame"   style="width:100px; height:100px; border: 0px"   src="/books/4/327/1/html/2/blank.htm"></iframe> <p> <a href="" onclick="parent.MyFrame.location.replace('choice1.htm'); return false">Red Pill</a><br /> <a href="" onclick="parent.MyFrame.location.replace('choice2.htm'); return false">Blue Pill</a><br /> </p> </body> </html>

Note in the onclick event handlers that the last statement in the JavaScript is a return statement returning a value of false. This prevents the default behavior of the linkwhich is to load the pagefrom being initiated.

The page also includes a script block that writes the string passed as a parameter to the iframe page. This, in turn, is passed in from either of the choice pages, the first of which is shown in Example 9-10.

Example 9-10. One of the pages loaded into the iframe

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body style="background-color: #f00"> <script type="text/javascript"> //<![CDATA[   window.parent.handleResponse("You picked the red pill"); //]]> </script> </body> </html>

Note that the page and the embedded page share the same parent.

One of the advantages to using the iframe for server communication is that it doesn't require any expertise with more esoteric communication mechanisms such as XML-RPC. The limitation is that there is no formalized API method for invoking services. All functionality is based more on pages loaded, and JS script processes.

Also, unlike other remote-scripting options, the history of options is maintained. In other words, the browser maintains state between choices.




Learning JavaScript
Learning JavaScript, 2nd Edition
ISBN: 0596521871
EAN: 2147483647
Year: 2006
Pages: 151

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net