jQuery 1.4 Reference Guide
上QQ阅读APP看书,第一时间看更新

A dynamic table of contents

As an example of jQuery in action, we'll build a small script that dynamically extracts the headings from an HTML document and assembles them into a table of contents for the page. Our table of contents will be nestled on the top-right corner of the page as shown in the following screenshot:

We'll have it collapsed initially as shown, but a click will expand it to full height.

At the same time, we'll add a feature to the main body text. The introduction of the text on the page will not be loaded initially, but when the user clicks on Introduction, the intro text will be inserted in place from another file.

Before we reveal the script that performs these tasks, we should walk through the environment in which the script resides.

Obtaining jQuery

The official jQuery web site (http://jquery.com/) is always the most up-to-date resource for code and news related to the library. To get started, we need a copy of jQuery, which can be downloaded right from the front page of the site. Several versions of jQuery may be available at any given moment; the most appropriate for us will be the latest uncompressed version. As of the writing of this book, the latest version of jQuery is 1.4.

No installation is required. To use jQuery, we just need to place it on our site in a web-accessible location. As JavaScript is an interpreted language, there is no compilation or build phase to worry about. Whenever we need a page to have jQuery available, we will simply refer to the file's location from the HTML document with a <script> tag as follows:

<script src="jquery.js" type="text/javascript"></script>

Setting up the HTML document

There are three pieces to most examples of jQuery usage—the HTML document itself, CSS files to style it, and JavaScript files to act on it. For this example, we'll use a page containing the text of a book:

<!DOCTYPE html>
<html lang="en">
  <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     <title>Doctor Dolittle</title>
    <link rel="stylesheet" href="dolittle.css" type="text/css" 
                                             media="screen" />
     <script src="jquery.js" type="text/javascript"></script>
     <script src="dolittle.js" type="text/javascript"></script>
  </head>
  <body>
    <div class="container">
      <h1>Doctor Dolittle</h1>
      <div class="author">by Hugh Lofting</div>
      <div id="introduction">
        <h2><a href="introduction.html">Introduction</a></h2>
      </div>
      <div class="content">
        <h2>Puddleby</h2>
        <p>ONCE upon a time, many years ago when our 
           grandfathers were little children--there was a 
           doctor; and his name was Dolittle-- John Dolittle,
           M.D.  &quot;M.D.&quot; means that he was a proper
           doctor and knew a whole lot. </p>
         
         <!-- More text follows... -->
      </div>
    </div>
  </body>
</html>
Note

The actual layout of files on the server does not matter. References from one file to another just need to be adjusted to match the organization we choose. In most examples in this book, we will use relative paths to reference files (../images/foo.png) rather than root-relative path (/images/foo.png). This will allow the code to run locally without the need for a web server.

Immediately following the standard <head> elements, the stylesheet is loaded. Here are the portions of the stylesheet that affect our dynamic elements:

/** =page contents
************************************************************/
#page-contents {
  position: absolute;
  text-align: left;
  top: 0;
  right: 0;
  width: 15em;
  border: 1px solid #ccc;
  border-top-width: 0;
  background-color: #e3e3e3;
}
#page-contents a {
  display: block;
  margin: .25em 0;
}
#page-contents a.toggler {
  padding-left: 20px;
  background: url(arrow-right.gif) no-repeat 0 0;
  text-decoration: none;
}
#page-contents a.arrow-down {
  background-image: url(arrow-down.gif);
}
#page-contents div {
  padding: .25em .5em .5em;  
  display: none;
  background-color: #efefef;
}

/** =introduction
************************************************************/

.dedication {
  margin: 1em;
  text-align: center;
  border: 1px solid #555;
  padding: .5em;
}

After the stylesheet is referenced, the JavaScript files are included. It is important that the script tag for the jQuery library be placed before the tag for our custom scripts; otherwise, the jQuery framework will not be available when our code attempts to reference it.

Note

To enable faster rendering of visual elements on the page, some developers prefer to include JavaScript files at the end of the document just before the closing </body> tag, so that the JavaScript file is not requested until the majority of the document has been loaded. For more information about this perceived performance boost, see http://developer.yahoo.com/performance/rules.html#js_bottom.

Writing the jQuery code

Our custom code will go in the second, currently empty, JavaScript file that we included from the HTML using <script src="dolittle.js" type="text/javascript"></script>. Despite how much it accomplishes, the script is fairly short.

jQuery.fn.toggleNext = function() {
  this.toggleClass('arrow-down')
    .next().slideToggle('fast');
  return this;
};

$(document).ready(function() {
  $('<div id="page-contents"></div>')
    .prepend('<a class="toggler" href="#">Page Contents</a>')
    .append('<div></div>')
    .prependTo('body'); 

  $('.content h2').each(function(index) {
    var $chapterTitle = $(this);
    var chapterId = 'chapter-' + (index + 1);
    $chapterTitle.attr('id', chapterId);
    $('<a></a>').text($chapterTitle.text())
      .attr({
        'title': 'Jump to ' + $chapterTitle.text(),
        'href': '#' + chapterId
      })
      .appendTo('#page-contents div');
  });
   
  $('#page-contents > a.toggler').click(function() {
    $(this).toggleNext();
    return false;
  });

  $('#introduction > h2 a').click(function() {
    $('#introduction').load(this.href);
    return false;
  });
});

We now have a dynamic table of contents that brings users to the relevant portion of the text, and an introduction that is loaded on demand.