How can I use Section headings to create a table of contents?

Beantwortet

7 Kommentare

  • Jim Davenport

    Hi seoj

    Depending on what you mean by "section headings", there are a number of ways to achieve this.

    In the example below I describe a code-based solution that will automatically generate a table of contents for your articles without you having to alter the article content.  It uses headings within an article to create the list:

    document.addEventListener('DOMContentLoaded', function() {
    var articleBody = document.querySelector('.article-body');
    var tableOfContents = document.getElementById('toc');

    // Do nothing if the article body or table of contents element doesn't exist
    if (!articleBody || !tableOfContents) {
    return;
    }

    // Get article content headings
    var headingSelector = 'h1, h2, h3, h4, h5, h6'
    var headings = Array.prototype.slice.call(articleBody.querySelectorAll(headingSelector));

    // Add an ID to each heading if they don't already have one
    Array.prototype.forEach.call(headings, function(heading, index) {
    heading.id = heading.id || 'heading-' + index;
    });

    // Only include headings with an ID
    headings = headings.filter(function(heading) {
    return heading.id
    });

    // Do nothing if there are fewer than 2 headings with IDs
    if (headings.length < 2) {
    return;
    }

    // Render the list
    var html = headings.map(function(heading) {
    return (
    '<li>' +
    '<a href="#' + heading.id + '">' +
    heading.childNodes[0].textContent +
    '</a>' +
    '</li>'
    );
    }).join('');

    html = '<ul>' + html + '</ul>';
    tableOfContents.insertAdjacentHTML('afterbegin', html);
    });

    It's self contained and so can be copy-pasted above or below the code that you currently have in your script.js file.

    What it does:

    1. Finds all headings (<h1> - <h6>) within the content
    2. Adds a dynamic ID to headings that don’t already have an ID
    3. Generates and displays a simple list of headings

    To have it display on all pages with two or more headings, insert a <div> with ID of "toc" into your article page template.  For example:

    <div class="article-body">
    <div id="toc"></div>
    {{article.body}}
    </div>

    When a visitor clicks on a heading link, the page is scrolled to that heading/section in the page.

    By changing the list markup (<ul> and <li> elements) and adding custom CSS, your can make the list look however you like.

    The code can also be used on other pages (e.g., category page) and reference other “section” types, not just headings, by altering the articleBody (i.e., parent element) and headingSelector variables.

    This example is a much simpler version of the custom Table of Content plugin that we’ve created as part of our theme customisation framework especially for this type of use case.

    Hope that helps!

    Jim

    Zenplates - Custom themes, plugins and apps for Zendesk

    1
  • seoj

    Thanks, Jim. Let me see if I can implement this. I don't have complete access to guide and also not much familiar with codes and themes. 

    this is what I mean by section heading <span class="section-heading">Introduction</span>

     

    0
  • Connor Mathena

    How do you recommend adding a title to the list? I want it to say something like "in this section"

     

    0
  • Jim Davenport

    Hey Connor Mathena

    Assuming you'd like the title to only be displayed when the list is displayed (which only happens when there are two or more heading with IDs in the article content), I'd recommend adding your title to the second to last line.  For example:

    html = '<h3>In this section</h3><ul>' + html + '</ul>';

    You can of course add any other HTML that you like there and style it all using custom CSS in your theme's style.css file.

    Cheers,

    Jim

    2
  • Connor Mathena

    Thank you so much Jim!

     

    0
  • Nicole S.
    Zendesk Community Team

    Thanks for jumping in with your answers, Jim! 

    0
  • Phil Sampson

    Is there an easy way to nest these based on h1,h2,h3

     

    Something like:

    <ul>
    <li>Coffee (H1)</li>
    <li>Tea (H1)
    <ul>
    <li>Black tea (h2)</li>
    <li>Green tea (h2)</li>
    </ul>
    </li>
    <li>Milk (H1)</li>
    </ul>
    0

Bitte melden Sie sich an, um einen Kommentar zu hinterlassen.

Powered by Zendesk