Tuesday, December 15, 2009

Creating and Loading a Dynamic Frame











Creating and Loading a Dynamic Frame


Because JavaScript can create page content on-the-fly, it's useful for loading dynamic data into frames based on a user's choice in another frame. Script 5.9 is a frameset that loads a dummy content page (Script 5.10) and Script 5.11, detailed next, that can create a page and load it into the main content frame. It creates a page that looks like Figure 5.9.


Script 5.9. This frameset loads a dummy page, ready to be replaced by JavaScript.





<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Setting one frame from another</title>
</head>
<frameset cols="30%,70%">
<frame src="left5.html" name="left" id="left" />
<frame src="frame5.html" name="content" id="content" />
</frameset>
</html>




Script 5.10. Speaking of which, here is the dummy page.





<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Content frame</title>
</head>
<body bgcolor="#FFFFFF">
</body>
</html>




Script 5.11. This script creates a page and loads it into the main content frame.





window.onload = initLinks;

function initLinks() {
for (var i=0; i<document.links.length; i++) {
document.links[i].onclick = writeContent;
document.links[i].thisPage = i+1;
}
}

function writeContent() {
var newText = "<h1>You are now looking at page " + this.thisPage + ".<\/h1>";

var contentWin = parent.document.getElementById("content").contentWindow;
contentWin.document.body.innerHTML = newText;
return false;
}






Figure 5.9. Here's the result of Script 5.8, a Web page written by a JavaScript. The content of the frame on the right was generated under script control.

[View full size image]




To load a dynamic frame from another frame:






1.

function initLinks() {
for (var i=0; i<document.links. length; i++) {
document.links[i].onclick = writeContent;
document.links[i].thisPage = i+1; }




The initLinks() function begins in the same way as in Script 5.8, by looping through the links on the page. Then, for each link, two things are set: the onclick handler for that link, and a new property is added: thisPage. The latter contains the page number to be displayed when that link is clicked, i.e., link 0 is "page 1", link 1 is "page 2", and so on. The onclick handler in the loop sets every link to call the writeContent() function when they're clicked.


2.

var newText = "<h1>You are now looking at page " + this.thisPage + ".<\/h1>";

var contentWin = parent.document.getElementById("content"). contentWindow;
contentWin.document.body.innerHTML = newText;




Here is the meat of the writeContent() function, which first declares and sets a variable, newText, and assigns it some text. Next, the contentWin variable is set, as shown earlier in this chapter in Script 5.6, and then we reset contentWin.document.body.innerHTML to newText. To explain this a bit further, given contentWin, we want the document it contains; then we get the body of that document, and then we reset innerHTML, which is the HTML contained within that tag.


3.
return false;


Lastly, writeContent() returns false, which tells the browser that it should not also load in the hrefs in the navigation bar's frame. Otherwise, the browser would do both. We've handled everything within JavaScript, so the href doesn't need to be loaded.



Tips



  • Why is there a backslash ("\") before the slash ("/") in step 2? According to the HTML standards, the browser may interpret the beginning of a closing tag ("</") as the end of the line. The backslash "escapes" the slash, allowing us to write out HTML without the chance of causing an error.

  • We're using parent.document.getElement... here versus document.getElement... that we used back in Script 5.6. That's because that JavaScript was going to be called by the frameset page, whereas here, it's being called by one of the framed pages. In the latter case, JavaScript has to go back up to its parent (i.e., the frameset) in order to look at the content page (another child of the parent).














No comments: