Skip to content

Instantly share code, notes, and snippets.

@milosh-96
Last active November 14, 2024 03:16
Show Gist options
  • Save milosh-96/0f9629856a4ccb906356201acdec97d5 to your computer and use it in GitHub Desktop.
Save milosh-96/0f9629856a4ccb906356201acdec97d5 to your computer and use it in GitHub Desktop.
Dynamic Table of contents
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
width: 700px;
margin: 0 auto;
}
.content > div {
min-height: 100vh;
}
</style>
</head>
<body>
<div class="container">
<div class="flex">
<div>
<ol id="toc-list">
</ol>
<select id="toc-select">
</select>
</div>
<div class="content">
<div>
<h3>Example 1</h3>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci, modi officia. Nesciunt reiciendis
debitis quis, consectetur voluptates magni eveniet perspiciatis consequatur molestiae quasi porro
laboriosam dicta ipsam fuga quam esse?
<hr>
</div>
<div>
<h3>Example 2</h3>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci, modi officia. Nesciunt reiciendis
debitis quis, consectetur voluptates magni eveniet perspiciatis consequatur molestiae quasi porro
laboriosam dicta ipsam fuga quam esse?
<hr>
</div>
<div>
<h3>Example 3</h3>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci, modi officia. Nesciunt reiciendis
debitis quis, consectetur voluptates magni eveniet perspiciatis consequatur molestiae quasi porro
laboriosam dicta ipsam fuga quam esse?
<hr>
</div>
<div>
<h3>Example 4</h3>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci, modi officia. Nesciunt reiciendis
debitis quis, consectetur voluptates magni eveniet perspiciatis consequatur molestiae quasi porro
laboriosam dicta ipsam fuga quam esse?
<hr>
</div>
<div>
<h3>Example 5</h3>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci, modi officia. Nesciunt reiciendis
debitis quis, consectetur voluptates magni eveniet perspiciatis consequatur molestiae quasi porro
laboriosam dicta ipsam fuga quam esse?
<hr>
</div>
<div>
<h3>Example 6</h3>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci, modi officia. Nesciunt reiciendis
debitis quis, consectetur voluptates magni eveniet perspiciatis consequatur molestiae quasi porro
laboriosam dicta ipsam fuga quam esse?
<hr>
</div>
<div>
<h3>Last section</h3>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Adipisci, modi officia. Nesciunt reiciendis
debitis quis, consectetur voluptates magni eveniet perspiciatis consequatur molestiae quasi porro
laboriosam dicta ipsam fuga quam esse?
<hr>
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
let headings = fetchHeadings();
let tableOfContentsList = document.getElementById("toc-list");
let tableOfContentsSelect = document.getElementById("toc-select");
assignUniqueIdToSectionHeading(headings);
loadElements(tableOfContentsList, headings);
loadElements(tableOfContentsSelect, headings);
document.getElementById("toc-select").addEventListener("change", (e) => {
window.location.hash = e.target.value;
})
})
let loadElements = function (targetElement, headings) {
targetElement.innerHTML = "";
let elements = [];
let tag = targetElement.tagName.toLowerCase();
elements = actions[tag](headings); // actions is a lookup object, and tag is a key there
elements.forEach(item =>targetElement.appendChild(item));
}
let prepareListElements = function (headings) {
let elements = [];
headings.forEach(heading => {
let element = document.createElement("li");
let link = document.createElement("a");
link.setAttribute("href", "#" + heading.id);
link.innerHTML = heading.innerHTML;
element.appendChild(link);
elements.push(element);
});
return elements;
}
let prepareSelectOptions = function (headings) {
let elements = [];
headings.forEach(heading => {
let element = document.createElement("option");
element.setAttribute("value", heading.id);
element.innerHTML = heading.innerHTML;
elements.push(element);
});
return elements;
}
let fetchHeadings = function () {
return document.querySelectorAll(".content h3");
}
let assignUniqueIdToSectionHeading = function (headings) {
let uniqueId = 1;
headings.forEach(heading => {
heading.setAttribute("id", "section-" + uniqueId);
uniqueId++;
});
}
let actions = {"ol":prepareListElements,"select": prepareSelectOptions};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment