SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : Dynamic Content Techniques : String-based Dynamic Content

First, we are going to create a table of contents out of the headers in your document using the Internet Explorer 4.0 string-based approach. For each item in the table of contents we will associate it with the content in the document.

The first step is to extract all the headers from the document. This is very simple and can be accomplished with one quick scan of the body's all collection:

function doLoad() {
  var s="<UL>"
  var cAll = document.body.all
  var iAll = cAll.length
  // Tags to look for
  var tagList = "H1;H2;H3;H4;H5;H6;"
  for (var i=0;i < iAll;i++)
    if (tagList.indexOf(cAll[i].tagName+";")>=0)
      s+="<LI class=\"toc" + cAll[i].tagName + "\">" + cAll[i].innerText
  s+="</UL>"
  document.body.insertAdjacentHTML("AfterBegin",s)
}

The above script creates and inserts a table of contents. However, this table of contents is static. We want the table of contents to be live so clicking on an entry takes you to the content in the page.

Solving this problem points out a weakness to the string-based approach. Our goal is to associate a reference to the header in the content with the entry in the table of contents. This reference cannot be described in the HTML string and needs to be applied directly to each individual LI element in the table of contents. This is where limitations of string-based HTML manipulation become apparent.

Our approach to solving this problem is two-fold. First, as we parse the document and find a header, we store the element's reference in an array. This array maps one-to-one with the entries we are creating in the table of contents. Next, after we insert the table of contents, we scan the table of contents list and associate each list item with the real content in the document:

function goTarget() {
	if (this.target)
		this.target.scrollIntoView()
}

function doLoad2() {
  var s="<UL ID=myTOC>"
  var cHeaders = new Array
  var cAll = document.body.all
  var iAll = cAll.length
  var tagList = "H1;H2;H3;H4;H5;H6;"
  for (var i=0;i<iAll;i++)
    if (tagList.indexOf(cAll[i].tagName+";")>=0) {
      cHeaders[cHeaders.length] = cAll[i]
      s+="<LI class=\"toc" + cAll[i].tagName + "\">" + cAll[i].innerText
    }
  s+="</UL>"
  document.body.insertAdjacentHTML("AfterBegin",s)
  var cTOC = document.all.myTOC.children.tags("LI")
  var iTOC = cTOC.length
  for (var i=0;i<iTOC;i++) {
    cTOC[i].target = cHeaders[i]
    cTOC[i].onclick = goTarget
  }
}

The last step is to improve the appearance of the table of contents. When generating the table of contents we assigned a class to each table of contents entry. All that is left to do is define the appropriate style sheet for each header level. Below is a very simple style sheet that indents each entry based on the header's level. With CSS you can make your style sheets as fancy or as simple as you want:

<STYLE>
#myTOC {cursor: hand}
.tocH2 {margin-left:10pt}
.tocH3 {margin-left:20pt}
.tocH4 {margin-left:30pt}
.tocH5 {margin-left:40pt}
.tocH6 {margin-left:50pt}
</STYLE>

While this approach works it is not a very elegant solution. It takes two passes to build the table of contents and takes a bit of work if you decide to change the HTML used to in the generated table of contents. Next we show you how to create the same solution using some of the new DOM methods of Internet Explorer 5.0.

Page 1:Dynamic Content Techniques
Page 2:String-based Dynamic Content
Page 3:Object-based Dynamic Content
Page 4:Conclusion
Page 5:Demonstration (IE4/5)