Create a dynamic table of contents with jQuery

You can easily auto-generate a clickable table of contents with jQuery if your text is divided by (the same level of) headers. All you need to do is to wrap your text in a container div and use the setInnerLinks() function.


First, be sure to load jQuery. The easiest way is to add this line to the head section of your HTML:

<script src="https://code.jquery.com/jquery-3.4.1.min.js"integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="crossorigin="anonymous"></script>

Next, you have to make sure your content is divided by headers and is wrapped by a div that has an ID.

<div id="content">

	<h3>First</h3>
	<p>Lorem ipsum dolor sit amet...</p>

	<h3>Second</h3>
	<p>Consectetur adipisicing elit.</p>

	<h3>Third</h3>
	<p>Eum possimus accusantium vero...</p>

	<h3>Fourth</h3>
	<p>Debitis doloremque perspiciatis!</p>

	<h3>Fifth</h3>
	<p>Voluptate, iusto harum veniam quo ipsa dicta...tatibus vitae eos, unde obcaecati eius sint voluptatem.</p>

	<h3>Sixth</h3>
	<p>Voluptatibus vitae eos, unde obcaecati eius sint voluptatem.</p>

</div>

(When testing the script, be sure to add more text to each paragraph if you want to test scrolling. You have to add enough content to make the vertical scrollbar appear. Of course, you can also just resize the browser window to achieve this.)

Finally add the script that will generate the table of contents before the closing body tag:

<script type="text/javascript">

	function setInnerLinks(containerID, elementClass){
		// Add an unordered list to the begining of the container
		$('#' + containerID).prepend("<ul id='" + containerID + "_links'></ul>");
		// Set the number of list items to 0
		var count = 0;
		// Find all headers
		$('#' + containerID + ' ' + elementClass).each(function() {
			// Set link id
			$(this).attr('id',('' + elementClass + '_' + (++count)));
			// Set link title
			var titleText = $(this).text();
			// Add the list item
			$('#' + containerID + '_links').append("<li><a href='#" + elementClass + '_' + count + "'>"+ titleText +"</a></li>");
			// Scroll to the header when clicking the link
			$('#' + containerID + '_links li a').last().click(function(e){
				e.preventDefault();
				var link = $(this);
				$('html,body').animate({ scrollTop: $($(link).attr("href")).offset().top }, (count * 200));
			});
		});
		// Add table of contents header 
		$('#' + containerID).prepend("<h3>Table of contents</h3>");
	};

	$(document).ready(function(){
		setInnerLinks('content', 'h3');
	});

</script>

Related Posts

Sorry, no similar posts found.