jQuery: counters on HTML elements

Suppose that we have a series of HTML headings of different levels and we want to add a counter with a progressive and nested numbering just before the text content of each heading. This is a feature that is often requested with tables of contents. We can use CSS generated content for that purpose, but this time we have to support even IE 7 and lower. In this case, we can't use CSS counters. And here it comes jQuery. Let's say that our HTML structure is as follows:

<h1>Title</h1>

<h2>Subtitle</h2>

<h3>Subsubtitle</h3>

<h2>Subtitle</h2>

<h3>Subsubtitle</h3>

<h4>Subsubsubtitle</h4>

We have 3 levels of headings, because we don't count the first one. Each one must be rendered as 2, 2.1, 2.1.1 and so on. We can use the jQuery's :header selector to loop over the headings, while incrementing and adding three counters for each heading:

$(document).ready(function() {

  var level2 = 0;
  var level3 = 0;
  var level4 = 0;
  

  $(':header').each(function() {
  
    var $header = $(this);
    var text = $header.text();
    var tag = $header[0].tagName.toLowerCase();
    var levelTag = tag.charAt(1);
    
    switch(levelTag) {
    
      case '2':
        
        level2 += 1;
        $header.text(level2 + '. ' + text);
        
        
        break;
      case '3':
        
        level3 += 1;
        $header.text(level2 + '. ' + level3 + ' ' + text);
        
        
        break;
      case '4':
        level4 += 1;
        $header.text(level2 + '. ' + level3 + '. ' + level4 + ' ' + text);
        
        
        break;
      default:
        break;
    
    
    
    }
    
    
    
  
  });

});

We get the level of each heading by extracting the second character from the tagName property of each element. Finally, we perform an action depending on the heading's level. You can see a demo below.

Demo

Live demo

This entry was posted in by Gabriele Romanato. Bookmark the permalink.

Leave a Reply

Note: Only a member of this blog may post a comment.