Context Bar to show Cloze note context dynamically

Ah, I think I know now.

The code is assuming that you are strictly setting headers in the correct structure.

See the Headings are important section here:

<h1> headings should be used for main headings, followed by <h2> headings, then the less important <h3> , and so on.

Problems occur, if the previous heading was an h2 and you add an h4. Problems also occur, if the first heading isn’t an h1 and you add an h1 somewhere.

The code in populateSideBar that does currentList = currentList.parentElement.parentElement is the problem. It’s going up two levels in the <ul> structure and ending up outside the sidebar when the heading structure is improper.

Updated populateSideBar with some error checking

  • In case the heading structure does not follow the proper order, this should at least stop it from adding stuff outside the sidebar
<script>
// Populate the sidebar with <li> elements
function populateSidebar() {
  const sidebarList = document.getElementById("sidebar-list");
  const headers = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
  // Duplicate the header structure in the sidebar as a nested <ul> list
  let currentList = sidebarList;
  let previousLevel = 1;
  function addHeader(header) {
    if (!currentList) {
      return;
    }
    const level = parseInt(header.tagName[1]);
    const listItem = document.createElement("li");
    const link = document.createElement("a");
    link.textContent = header.textContent;
    // If the header doesn't have an id, assign it the text content
    if (!header.id) {
      header.id = header.textContent;
    }
    link.href = "#" + header.id;
    listItem.appendChild(link);
    if (level > previousLevel) {
      const newList = document.createElement("ul");
      currentList.appendChild(newList);
      currentList = newList;
    } else if (level < previousLevel) {
      for (let i = 0; i < previousLevel - level; i++) {
        // We want to get currentList.parentElement.parentElement but not go beyond the top level
        // which is sideBarList
        currentList = currentList.parentElement
        if (currentList.id !== "sidebar-list") {
          currentList = currentList.parentElement
        }
      }
    }
    currentList?.appendChild(listItem);
    previousLevel = level;
  }
  headers.forEach(addHeader);
}


populateSidebar();
</script>
1 Like