- Content and Markup
- Build the TOC with JavaScript
- Making the Table of Content Collapsible
- Display the Selected Answer
- Summary
Display the Selected Answer
The last phase of our JavaScript enhancements is the capability to display the selected answer just below the TOC instead of jumping to the answer anchor somewhere within the document. This enhancement ensures that the TOC will always stay (at least partially) visible.
To get this functionality, we need to hide all question-and-answer pairs after the page is loaded and display only the one the user requests by clicking on a second-level TOC link. The FAQ content is hidden by setting the style.display attribute of all H2, DT, and DD elements within the DIV with id=faq to "none":
function hideQA() { var faqList = xGetElementById("faq"); if (!faqList) return; var headers = xGetElementsByTagName("h2",faqList); for (var i = 0; i < headers.length; i++) headers[i].style.display = "none"; var questions = xGetElementsByTagName("dt",faqList); for (var i = 0; i < questions.length; i++) questions[i].style.display = "none"; var answers = xGetElementsByTagName("dd",faqList); for (var i = 0; i < answers.length; i++) answers[i].style.display = "none"; }
To display the selected answer once the user clicks on a link in the second-level TOC entry, we need to modify the onclick event of the corresponding A element that is generated in the buildToc function. The modified part of that function is included below:
for (var j = 0; j < dtlist.length; j++) { ... omitted ... var aElem = document.createElement("A"); aElem.onclick = DisplaySingleAnswer; aElem.href = "#click_" + idCount; ... omitted ... }
The DisplaySingleAnswer function performs the following tasks:
- It computes the target question ID from the href attribute of the clicked A element.
- It finds the target DT element.
- If the target DT element is found, it hides all questions and answers to ensure that no other FAQ text is visible.
- It clears the style.display attribute of the target DT element, thus making it appear on the page.
- It scans all the HTML elements following the DT element, skipping the text nodes (whitespaces between HTML tags appear as text nodes in the DOM tree) and showing all DD elements immediately following the target DT element (making sure that the whole answer will be displayed, even if it’s written in multiple DD elements).
The source code of this function is included in the following listing:
function DisplaySingleAnswer() { var answerID = this.href.replace(/.*#/,""); var dtElem = xGetElementById(answerID); if (!dtElem) return; var ddElem,nodeName; hideQA(); dtElem.style.display = ""; ddElem = dtElem; do { ddElem = ddElem.nextSibling; if (!ddElem) break; nodeName = ddElem.nodeName.toLowerCase(); if (nodeName == "#text") continue; if (nodeName != "dd") break; ddElem.style.display = ""; } while(ddElem); }