Create Auto-generated Table of Contents with HTML Slots

Table of contents can severely urge a user knowledge of many websites, for instance documentation sites or online encyclopedias like Wikipedia. A well-designed list of essence gives an overview of a page and helps users fast navigate to a territory they are meddlesome in.

Traditionally, we can emanate list of essence possibly in HTML or with JavaScript, though a newly standardised HTML slots yield a middle approach between a two. HTML Slot is a web customary that allows we to add placeholders to a web page and after fill it with calm dynamically.

When to use a slot tag

You can place slot tags into a list of essence inside your HTML file, so a slots after can be filled with a applicable headings and subheadings. When a headings are altered a slots are auto-updated.

With this technique, we need to emanate a HTML source formula of a list of essence manually. JavaScript usually auto-generates a calm calm of a list of contents, based on a headings or subheadings on a page.

If we don’t wish to list of essence to be benefaction in a HTML we need to generate both a blueprint and a calm with JavaScript.

1. Create a HTML

The HTML source formula for a TOC (table of contents) will be inside a template tag. The formula inside template doesn’t get rendered until it’s combined to a request by JavaScript. Our TOC will have placeholders, hold in slot tags, for all a headings and subheadings found in a document.

The name charge of any slot will have a same value as a slot charge in their analogous headings and subheadings in a document.

Below, we can see a sample HTML article with some headings and subheadings. The div during a commencement is where we’ll insert a auto-filled TOC.

div id='toc'/div
article
pVelociraptor (/vᵻˈlɒsᵻræptər/; definition "swift seizer" in Latin) is a …/p

h2 slot='h-1'Description/h2
pVelociraptor was a mid-sized dromaeosaurid, with adults …/p

	h3 slot='sh-1-1'Feathers/h3
	pFossils of dromaeosaurids some-more obsolete than …/p 

h2 slot='h-2'History of discovery/h2
pDuring an American Museum of Natural History speed …/p

h2 slot='h-3'Classification/h2
pVelociraptor is a member of a organisation Eudromaeosauria, a subsequent sub-group of …/p

h2 slot='h-4'Paleobiology/h2
pThe "Fighting Dinosaurs" specimen, found in 1971, preserves a …/p

	h3 slot='sh-4-1'Scavenging behavior/h3
	pIn 2010, Hone and colleagues published a paper on …/p

	h3 slot='sh-4-2'Metabolism/h3
	pVelociraptor was warm-blooded to some degree, as it compulsory a …/p

	h3 slot='sh-4-3'Pathology/h3
	pOne Velociratoptor mongoliensis skull bears dual together …/p
/article

As we can see, any streamer is given a singular slot value.

And, here’s a HTML formula of a TOC, inside a template tag.

template
ul
	li
		slot name='h-1'/slot
		ul
			lislot name='sh-1-1'/slot/li
		/ul
	/li
	lislot name='h-2'/slot/li
	lislot name='h-3'/slot/li
	li
		slot name='h-4'/slot
		ul
			lislot name='sh-4-1'/slot/li
			lislot name='sh-4-2'/slot/li
			lislot name='sh-4-3'/slot/li
		/ul
	/li
/ul
style
	ul {
		list-style: none;
	}
/* … */
/style
/template

In a dual formula snippets above, notice a matching slot and name attributes inside a headings and a slot tags.

2. Number a headings

Before looking into a JavaScript code that will supplement a TOC from a template to a document, let’s add sequence numbers for a headings, regulating CSS counters.

article {
	counter-reset: heading;
}
article h2::before {
	counter-increment: heading;
	content: '0'counter(heading)': ';
}

Ensure that a counter-reset order belongs to a component that’s a immediate primogenitor of all a titles carrying a slot attribute (which is a article component in a code).

3. Insert a TOC into a document

Now, we supplement a book that inserts a TOC above a article tag, inside a div id='toc'/div container.

templateContent = document.querySelector('template').content;
article = document.querySelector('article').cloneNode(true);
article.attachShadow({  mode: 'closed' }).appendChild(templateContent.cloneNode(true));
document.querySelector('#toc').appendChild(article);

The formula dash above creates a duplicate of article and attaches a Shadow DOM Tree to it. We also add a duplicate of template‘s content to this Shadow DOM tree.

Then, a cloned article is extrinsic into a div id='toc' element. The article component is now benefaction in a TOC as well, however usually a headings and subheadings that found a placeholder inside a TOC are visible.

If we would reset a CSS opposite during a body or html component instead of article, a opposite would have counted a list of headings inside a TOC as well. That’s because we should reset a counters during a evident primogenitor of a headings.

Here is a screenshot of a output:

4. Add hyperlinks

If we wish to link a TOC titles to their particular headings and subheadings by adding id to a headings and anchoring their analogous TOC calm we will have to remove a repeated id values from a cloned article.

div id='toc'/div
article
pVelociraptor (/vᵻˈlɒsᵻræptər/; definition "swift seizer" in Latin) is a …/p

h2 id='h-1' slot='h-1'Description/h2
pVelociraptor was a mid-sized dromaeosaurid, with adults …/p

h3 id='sh-1-1' slot='sh-1-1'Feathers/h3
pFossils of dromaeosaurids some-more obsolete than …/p 
!-- ... --
/article

As we can see above, a id charge is combined to each streamer and subheading in a article.

And, a titles inside a list of essence are anchored:

template
ul
li
		a href='#h-1'slot name='h-1'/slot/a
		ul
			a href='#sh-1-1'lislot name='sh-1-1'/slot/li/a
		/ul
/li
!-- ... --
/ul
/template

In a additional line above, all id attributes are removed from a cloned article before attaching a Shadow DOM tree to it.

templateContent = document.querySelector('template').content;
article = document.querySelector('article').cloneNode(true);
article.querySelectorAll('*[id]').forEach((ele)={ele.removeAttribute('id')})
article.attachShadow({  mode: 'closed' }).appendChild(templateContent.cloneNode(true));
document.querySelector('#toc').appendChild(article);

See a screenshot of a linked list of contents below:

Github demo

You can check out, download, or flare a formula used in this post from a Github Repo.

Add Comment