Explosion Pills!

jQuery Headerlinks Plugin

Introduction

I created a jQuery plugin for practice and because I thought it would be a fairly good idea. Headerlinks dynamically and automatically (and quickly) creates an organized table-of-contents list anywhere you want on the page in any style.

The headerlinks plugin (if you are using JS) is what is making the nice table-of-contents block at the top of this page. I have no doubt that it is the greatest thing ever made.

Purpose

The jQuery headerlinks plugin will automatically create a table of contents block anywhere on the page. It has a tremendous amount of flexibility and does many things automagically. The block above was created using only the defaults. Frankly I customized the defaults specifically for my site, but adding to them should take fairly minimal effort.

If you are too lazy to come up with a dynamic script that creates this block with your web language of choice, you can fall back on this plugin to do it for you quickly and easily.

Documentation

Below is the API for headerlinks and how to tailor it to meet your needs.

Running headerlinks

Include the script file like any other script file. To run it, call:
$("#table-of-contents").headerlinks();
This assumes that table-of-contents is where you want it. You have to include the container on your own, but you can also style it any way you like. You can use headerlinks() to style it. More on that later.

API

You can pass any of the following options to headerlinks(). They are all optional and can be included in any order. Include as instructed. Example inclusion:
   $("#table-of-contents").headerlinks({
      debug: false
      , deny: ['.holy_header', '.master_title', '.article_title']
      , hierarchy: {
         'h2': {num: 1}
         , 'h3': {num: 2, css: {'margin-left': '20px'}}
      }
   });

minlen

Minimum number of elements that must be included in the table of contents in order for it to be dislpayed at all. This is just an integer. You can set it to zero (or a negative number if you like) or any other number that meets your needs.

minlen ignores any hierarchies. It is based purely on the number of matched elements and does not care about their details.

default: 5

incl

List of selectors you want to include. This overlaps with headers (see below). You can include as an array or comma-separated list, or even some combination if you wish. This will work: {incl: ['selone, seltwo', 'selthre']}.

incl allows you to include not just <h> tags but any tags that fulfill the requirements of incl. They may need more specifications to work as you desire.

default: []

deny

Opposite of incl, deny is a list of selectors that will be left out of the table-of-contents structure. deny can be built in the same way as incl: as a comma-separated list or array.

deny overrides incl, so if an element meets the conditions of both, it will not have an associated headerlinks entry.

Elements matched by deny have no impact on table-of-contents structure whatsoever even if they appear between other headerlinks entries.

default: []

headers

Headerlinks was designed with the assumption that header tags, <h1> through <h3> would be used to design the table of contents with a certain hierarchy. As such, you can define whether header tags should be automatically included or denied, and how deep they should go.

headers has two attributes: use and depth. use defines whether they should be used at all, and depth indicates the largest number of the header tag to be used. Alter in such a way:
   {headers: {use: true, depth: 4}}
If you are using headers, adding them to incl is redundant.

deny overrides headers as well.

If headers.depth is not between 1 and 6, it will default to 3.

default: {use: true, depth: 3}

numbers

A boolean. If it is set, all table-of-contents entries will be preceded by numbers based on the hierarchy. If it is not set, no numbers. The table-of-contents with this page operates with this feature on.

default: true

hierarchy

hierarchy is a complex attribute that can be used to strongly affect how the table of contents entries in the container are affected. It is an object that has attributes that are selectors and as such must be strings. Each selector has attributes of css and num.

css

CSS styles that are applied to the table-of-contents entry that corresponds to the selected element. For instance: {'h4': {css: {'margin-left': '40px'}}} will add margin-left of 40px to table-of-contents entries corresponding to <h4> tags found by headerlinks. Note that these are not automatic. If you change the defaults, you must fully rewrite the hierarchy to work the way you want.

num

This only needs to be used if numbers == true.

Indicates how deep in the hierarchy tree the entry is. The corresponding entry created in the table-of-contents block will count its number based on the depth in the tree. For example: {'h4': {num: 2}} will cause table-of-contents entries corresponding to <h4> to be preceded by two period-separated numbers. If num is not specified, it defaults to 1.

If you have a num: 1 and num: 3, the latter will be treated as if it were num: 2. You should try to avoid this if you can as I can't vouch for this plugin to work 100% properly if there is such an error, but it seems to handle it gracefully.

Counting is relative to the depth in the tree. If all entries have num: 1, the TOC will count 1, 2, 3, 4 ... If you have one element followed by two other elements with a higher num each time, it will count 1, 1.1, 1.2, 2, 2.1, 2.2, 3, 3.1, 3.2 ... Note how the second number per entry counts relative to the first number.

Also note that css and num have no dependency on each other. You can use hierarchy to apply css to any table-of-contents entry you want even if it is the same num in the hierarchy as another with different styling.

default: Sets <h2> to <h6>. Each has num correspond to the number in the tag, and its left margin is 20 pixels times that number minus one.

container

CSS styling for the container element. These styles will be used in addition to any styles that are set to the container by stylesheets. If they overlap, container takes precedence. Use this attribute in the same way as you would the jQuery.css() function: as an object or string.

That is to say, $("#container-element").css(container) is literally called.

default: { 'width': '30%' , 'border': '1px solid black' , 'padding': '10px' , 'font-size': '10px' }

debug

headerlinks will do its best to detect some non-fatal errors that may either cause headerlinks to not work as you expect or in the worst case not show anything at all. The debug block is red and fixed to the top of the page in a very obvious, intrusive, and annoying way. You should consider turning this off once you have everything working.

default: true

init

If you include a valid headerlinks ID in the hash and init is set, the page will take you to the corresponding anchor. This allows you to create bookmarks including the hash and to send links to others and take them to the page location you want. Set to false and the page will always load at the top regardless of the hash.

default: true

Demo

This page itself is a demo for using headerlinks. Here is an abridged description of how to use headerlinks in the same way as this page:
   <html>
   <head>
      <script type="text/javascript" src="/_js/jquery.min.js"></script>
      <script type="text/javascript" src="/_js/jquery.headerlinks.min.js"></script>
      <script type="text/javascript" src="/_js/headerlinks_renderer.js"></script>
   </head>
   <body>
      <h1 class="title">jQuery Headerlinks Plugin</h1>
      <h1>Introduction</h1>
      <h1>Purpose</h1>
      <h1>Documentation</h1>
         <h2>Running headerlinks</h2>
         <h2>API</h2>
            <h3>minlen</h3>
            <h3>incl</h3>
            <h3>deny</h3>
            <h3>headers</h3>
            <h3>numbers</h3>
            <h3>hierarchy</h3>
               <h4>css</h4>
               <h4>num</h4>
            <h3>container</h3>
            <h3>debug</h3>
      <h1>Demo</h1>
      <h1>Download</h1>
   </body>
   </html>
/**
 * headerlinks_renderer.js
 */
$(function () {
   var table_of_contents = document.createElement('div');
   $('.title').after(table_of_contents);

   $(table_of_contents).headerlinks({
      debug: false
      , deny: '.title'
      , headers: {use: true, depth: 4}
   });
});

Download

Bugs

Report any bugs to: bugs@truthanduntruth.com

Please specify your email is about the jQuery headerlinks plugin in the subject.

License

Headerlinks has no license and is free for both commercial and personal use. I only ask that you retain the comment at the top of the script giving me credit.