Create a Table of Contents automatically
2016년 8월 18일에 게시됨
Much like the author of this article, our company needs a way to automatically generate a table of contents for large articles. After finding out we can use jQuery, I put together a script that will automagically create a tiered table of contents based on the Header tags used in the article.
All you need to do is paste the Javascript in this page into the Javascript section of your Articles:
Click on the JS tab, then paste in the code at the end:
That should do it.. as long as you've used proper heading tags (H1, H2, etc), a Table of Contents will be created any time you load the article.
You can see a live example here: http://codepen.io/ngalluzzo/pen/kXqyVQ?editors=1010
3
55
댓글 55개
Warren Lam
Hi Zivbs and Nicolas,
I tried to use the same code from Zivbs but I can only output as the following without the TOC/links. Do I need to update the CSS or what did I do wrong? Any idea?
Result:
1 Title
2 Second Titles
3 Subtitle
3.1 Subtitle2
3.1.1 Sub Sub3
3.1.1.1 Sub Sub4
4 Sub Sub5
4.1 Sub Sub6
5 Third Title
5.1 The sub
0
dave
Hi - can anyone share the latest working TOC js? I'm still having issues with it executing within the custom theme. Is it picking up jquery properly? I also see an 'unexpected end of script error' but all brackets and such are correct. Is something else happening? Dave
0
Jessie Schutz
Welcome to the Community, Dave! I'm going to check with our Community Moderators to see if they have any insight on this. Otherwise, hopefully some of our other awesome Community members will be able to help!
0
dave
Hi - Has anyone created a TOC w/o errors? I'm having problems with the script not recognizing all header tags and also creating run-on hierarchies like that depicted below. Is there an updated, tested script? Also, it seems to be hit-and-miss in executing. Anything missing in the first few JS lines? Anything required in the document head or header templates? Thanks. Dave
/*
* jQuery v1.9.1 included
*/
$(document).ready(function() {
var $headers = $('.article-body h1');
if ($headers.length > 1) {
--------------------------
0
Ziv Bass Specktor
Sure, Ashwini. Here it goes:
/*** Table of contents code ***/
var $headers = $('.article-body h2');
if ($headers.length > 0) {
var $toc = $('<div class="toc">');
var $firstUl = $('<ul>');
var $currentUl = $firstUl;
var previous_level = 2;
$firstUl.appendTo($toc);
$toc.prependTo('section.article-info');
// start with first H1
insertHeading($headers[0]);
}
function insertHeading(heading) {
var $heading = $(heading);
// what level heading are we on?
var current_level = headingLevel(heading);
// if it's an H2, add it to the original list
if (current_level === 2) {
newLi($heading, $firstUl);
$currentUl = $firstUl;
}
// if it's the same as the one before it, add it to the current list
else if (current_level === previous_level) {
newLi($heading, $currentUl);
}
// if it's one level higher than the one before it... time to make a new nested list
else if (current_level > previous_level) {
nestUl();
newLi($heading, $currentUl);
}
previous_level = current_level;
var $nextHeading = $heading.nextAll("h1, h2, h3, h4, h5, h6").first()[0];
// if there's any headings left... run this again
if ($nextHeading) insertHeading($nextHeading);
}
// adds a new UL to the current UL
function nestUl() {
var $newUl = $('<ul>');
$newUl.appendTo($currentUl);
$currentUl = $newUl;
}
// returns a numerical value for each heading
function headingLevel(heading) {
switch (heading.nodeName) {
case 'H1':
return 1;
break;
case 'H2':
return 2;
break;
case 'H3':
return 3;
break;
case 'H4':
return 4;
break;
case 'H5':
return 1;
break;
case 'H6':
return 6;
break;
default:
return 0;
}
}
// inserts a new line to the current list
function newLi(heading, $list) {
var $heading = $(heading);
var $wrapper = $('<li></li>');
//var $link = $('<a>').prop('href', '#' + $heading.prop('id'));
var $anchorname = $heading[0].outerText.replace (/\s/g,'')
var $link = $('<a>').prop('href', '#' + $anchorname);
$link.html('<span class="index"></span> ' + $heading.text());
$link.appendTo($wrapper);
$wrapper.appendTo($list);
var place_in_parent = $list.children('li').length;
if ($list.parent()[0].nodeName === 'DIV') {
$link.find('.index').text(place_in_parent)
} else {
$link.find('.index').text($wrapper.parent().prev('li').find('.index').text() + '.' + place_in_parent)
}
$heading.html("<a name=\"" + $anchorname + "\"></a>" + $link.find('.index').text() + ' ' + $heading.text());
}
/*** End of Table of contents code ***/
0
Ashwini Sukhdeve
Ziv, would you mind sharing the working code here? Thank you!! 😀
0
Jennifer Rowe
Hi Zivbs,
Have you seen our complete list of Help Center tips?
Check it out for more goodies.
And be sure to follow the post so you get updates.
0
Ziv Bass Specktor
Nicolas, thanks again for this code.
I made a few small changes and now it works great.
If you have anymore such cool snippets to share don't be shy :-)
0
Ziv Bass Specktor
Nicolas, thanks a lot for your swift answer. I really appreciate it.
Yes, I was referring to line 81. The addition of $link makes sense.
You run on the headers which you get by:
var $headers = $('.article-body h1');
The problems:
1. '.article-body h1' doesn't exist in the article template.
When I changed the code to 'h1' at least it found the main header.
2. It doesn't find any other h2, h3 etc. in the html so that's the reason why it doesn't do much.
Any idea how to fix this?
0
Nic Galluzzo
Ziv,
Are you referring to line 81? The full line is: $link.appendTo($wrapper);
As long as you've corrected that type error and added it to the Custom Theme, that's all you need
0
댓글을 남기려면 로그인하세요.