The list of books on Required Reading is starting to get a bit long, so I decided to add a table of contents (TOC). It's a drag to update the TOC everytime I add a book, so of course Javascript (JS) came to mind. But I didn't know whether Blogger uses jQuery so I decided to go old school and do puro JS.
First I added an id
attribute to the book headers that I could use to link to them. At first I also thought that I could just grab all of the headers of type h2
but it turns out, duh, that there were a lot of h2
headers already in the template for the page, so I got a bunch of unrelated TOC entries. So instead I created a class that I could use to identify my book headers. Probably other ways I could have resolved that conundrum, so if you, yes you, have any bright ideas, please enlighten us! Thanks!
One cool thing I learned from pure JS is that document
has an attribute similar to jQuery's $(Document).ready()
function called document.body.onload
, altho now I see in jQuery's documentation that the difference is that jQuery runs your JS as soon as the DOM is loaded and doesn't wait for assets like images to load as well, since they take longer.
Source
Here is the Gist of it.<html> | |
<head> | |
<!-- either head or body --> | |
<style type="text/css"> | |
.toc_item { | |
color: green; | |
} | |
</style> | |
<!-- css class --> | |
</head> | |
<body> | |
<div id="toc"> | |
</div> | |
<!-- TOC --> | |
<h2 class="toc_item">item #1</h2> | |
<p>Item 1 is very cool.</p> | |
<!-- item #1 --> | |
<h3 class="toc_item">item #2</h3> | |
<p>Item 2 is super fun.</p> | |
<!-- item #2 --> | |
<h2 class="toc_item"><a href="http://www.example.com">item #3</a></h2> | |
<p>Item 3 is awesome.</p> | |
<!-- item #3 --> | |
<!-- content --> | |
<script> | |
/* Generate TOC | |
* | |
* :param classname: Class to which all TOC items belong. | |
* :param tocID: ID of the TOC element, should be <div></div>. | |
*/ | |
function gen_toc(classname, tocID) { | |
var alltags = document.getElementsByClassName(classname); // all TOC items | |
var toc_content = "<h2>Table of Contents</h2><ol>"; // inner HTML content of TOC element | |
var toc_link = ' <a href="#' + tocID + '">(' + tocID + ')</a>'; // link to TOC element for each TOC item | |
for (var i = 0; i < alltags.length; i++) { | |
var toc_item = alltags[i].innerText; // just the inner text from the TOC item's element, ie: no links | |
var toc_item_enc = encodeURIComponent(toc_item).replace(" ", "-").toLowerCase(); // make URL safe ID string | |
alltags[i].setAttribute("id", toc_item_enc); // set ID of TOC item | |
alltags[i].innerHTML += toc_link; // add back link to TOC from TOC item | |
toc_content += '<li><a href="#'; | |
toc_content += toc_item_enc; | |
toc_content += '">'; | |
toc_content += toc_item; | |
toc_content += '</a></li>'; | |
}; | |
toc_content += '</ol>'; | |
console.log(toc_content); | |
var toc = document.getElementById(tocID); // TOC element | |
toc.innerHTML = toc_content; | |
}; | |
document.body.onload = gen_toc("toc_item", "toc"); | |
</script> | |
<!-- toc script --> | |
</body> | |
</html> |
No comments:
Post a Comment