sinanisler logo

Table of Contents, Automatic Heading Link List Generation

Add an element with a unique ID (toc-container in this example) to your HTML where you want the table of contents.

document.addEventListener("DOMContentLoaded", function() {
    // Select all h2 and h3 elements
    const headers = document.querySelectorAll("h2, h3");

    // If there are no headers, exit the function
    if (headers.length === 0) {
        return;
    }

    // Find the specified container for the table of contents
    const tocContainer = document.getElementById("toc-container");
    if (!tocContainer) {
        console.error("Table of contents container not found.");
        return;
    }

    // Create a container for the table of contents
    const toc = document.createElement("div");
    toc.id = "table-of-contents";
    toc.innerHTML = "<div class='toc-title'>Table of Contents</div>";

    // Create an unordered list for the links
    const list = document.createElement("ul");

    // Iterate over the headers and create list items with links
    headers.forEach((header, index) => {
        // Assign a unique ID to each header
        header.id = "heading-" + index;

        // Create a list item and a link for the table of contents
        const listItem = document.createElement("li");

        // Add class to listItem based on header tag name (h2 or h3)
        if (header.tagName === 'H2') {
            listItem.className = 'h2';
        } else if (header.tagName === 'H3') {
            listItem.className = 'h3';
        }

        const link = document.createElement("a");
        link.href = "#" + header.id;
        link.innerText = header.textContent;
        listItem.appendChild(link);

        // Append the list item to the unordered list
        list.appendChild(listItem);
    });

    // Append the unordered list to the table of contents container
    toc.appendChild(list);
    tocContainer.appendChild(toc);

    // Optional: Add smooth scrolling
    list.addEventListener("click", function(event) {
        if (event.target.tagName === "A") {
            event.preventDefault();
            const targetId = event.target.getAttribute("href").slice(1);
            document.getElementById(targetId).scrollIntoView({
                behavior: "smooth"
            });
        }
    });
});

Demo;

See the Pen table of contents native js example, article title list by sinanisler (@sinanisler) on CodePen.

Leave the first comment