Dynamically-Loaded Site

This version stores the text for each topic in a separate HTML file, and uses AJAX to load the content for the topic dynamically into a div on the page. It uses the free JQuery JavaScript library to provide the AJAX routines it needs, and ensure cross-browser compatibility.

Click here to open the demo in a new window:

Dynamically-Loaded Site Demo


  • Extensible, fast.


  • Title and address bar don't change to reflect current topic, bookmarks not possible, and browser Previous and Next buttons not supported[1].
  • Not search-engine friendly.
  • Needs JavaScript and JQuery.


This version of the help comprises the following files:

Filenames Description
01-Intro.html, 02-Site.html, etc. The HTML files for each topic.
index.html The main page.
basic.css, jquery-1.7.2.min.js CSS definitions and JQuery file.

If you choose a different naming convention for the topic files you will need to change the LoadPage() routine, as this calculates the link ids from the filename number prefix.

The design uses three div blocks, one fixed one for the heading, and two scrolling blocks for the contents/index, and topics:


The topics are loaded into an empty div used as a placeholder:

<div id='content'> </div>

This is given an absolute position, with the top positioned below the heading and the bottom at the bottom of the window, to ensure that the content can be scrolled within the div without scrolling the whole window[2]:

#content {
  position: absolute;
  top: 60px;
  bottom: 0;
  margin-left: 180px;
  width: 720px;
  overflow-y: auto;


Each entry in the table of contents could include an onClick event to load in the appropriate page:

<a href="#" onClick="$(#content).load('01-Intro.html');">Introduction</a>

A refinement would be to provide a LoadPage() function to load the content, so the links would become:

<a href="#" onClick="LoadPage('01-Intro.html');">Introduction</a>

A better approach is to include the reference in the href parameter, and access it via the this keyword. This has the advantage that web site tools, like Dreamweaver, will then automatically manage the links. For example, renaming one of the files will automatically update the hrefs:

<a href="01-Intro.html" onClick="LoadPage(this);">Introduction</a>

Finally we can use the JQuery .on() function to define the onClick event handler for all "a" links automatically:

$(document).on("click", "a", function() {

The links include an id parameter, to allow us to highlight the current link, so the final format of the links is:

<a id="p01" href="01-Intro.html">Introduction</a>


Likewise, the index entries are just:

<a href="06-Statistics.html#a06-5">Statistics, spot</a>

Contents and index highlighting

The routine LoadPage() loads the page from the specified href, and performs the appropriate contents and index highlighting:

function LoadPage(link) {
  var hash = link.hash, href = link.href;
  $('#content').load(href, function() {
    if (hash=='') {
    else {
      var st = $(hash).position().top;
  HilightContents('#p' + href.substr(href.lastIndexOf('/')+1, 2));
This routine works as follows:
  • First the page specified in the href is loaded.
  • If the href parameter doesn't have a hash suffix the link is a page URL. The scroll of the content div is reset to zero.
  • If the href parameter does have a hash suffix the anchor is scrolled to the top and highlighted, by setting its class to hi.
  • The two-digit filename prefix is used to construct an id, and this is passed as the parameter to HilightContents() to highlight the appropriate contents entry.

Here's the definition of HilightContents():

var greybar = '';

function HilightContents(id) {
  greybar = id;

Cross references

Cross references use the same format as the other links:

<a href="03-Associates.html">

Note that currently the example assumes that there are no links to external URLs; these will need to be excluded from the click event handler.

  1. ^ These issues can be solved by using the pjax or History.js libraries; thanks to Rob Meek for pointing this out.
  2. ^ Thanks to Steve Sanderson for showing how to achieve this

blog comments powered by Disqus