Skip to content

Commit

Permalink
Merge pull request #282 from ELIXIR-Belgium/anchor-fix-2
Browse files Browse the repository at this point in the history
Improve anchor link behavior and TOC
  • Loading branch information
bedroesb authored Sep 9, 2024
2 parents bd0f510 + 0f75135 commit 4b6f6bc
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 50 deletions.
32 changes: 31 additions & 1 deletion _includes/toc.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
<script>
$(document).ready(function () {
$('#toc-contents').toc({ minimumHeaders: {{site.theme_variables.toc.min_headings | default: 1 }}, listType: 'ul', classes: { list: 'list-unstyled' }, noBackToTopLinks: true, showSpeed: 0, headers: '{{site.theme_variables.toc.headings | default: 'main h2' }}' , title: '<strong class="my-2">On this page</strong><hr class="my-2">' });
// Ensure that the TOC is generated after the document is fully loaded
$('#toc-contents').toc({
minimumHeaders: {{ site.theme_variables.toc.min_headings | default: 1 }},
listType: 'ul',
classes: { list: 'list-unstyled' },
showSpeed: 0,
headers: '{{site.theme_variables.toc.headings | default: "main h2" }}',
title: '<strong class="my-2">On this page</strong><hr class="my-2">'
});
// After generating the TOC, check the hash in the URL and scroll to the anchor if present
if (window.location.hash) {
var target = $(window.location.hash);
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 0);
}
}
// Allow the browser to handle the scrolling to the anchor
$('#toc-contents a').on('click', function (e) {
e.preventDefault(); // Prevent the default link click behavior

var target = this.hash; // Get the hash (e.g., #heading-id)
var $target = $(target); // Find the element with the corresponding ID

if ($target.length) {
// Change the URL hash
window.location.hash = target;
}
});

});
</script>
<button id="btn-toc-hide" class="btn bg-light d-xl-none hover-primary mb-3" type="button" data-bs-toggle="collapse" data-bs-target="#toc-contents" aria-expanded="true" aria-controls="toc-contents">
Expand Down
78 changes: 29 additions & 49 deletions assets/js/toc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
(function ($) {
$.fn.toc = function (options) {
var defaults = {
noBackToTopLinks: false,
title: '<i>Jump to...</i>',
minimumHeaders: 3,
headers: 'h1, h2, h3, h4, h5, h6',
Expand All @@ -16,7 +15,7 @@
toc: ''
}
},
settings = $.extend(defaults, options);
settings = $.extend(defaults, options);

function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
Expand All @@ -25,32 +24,32 @@
}

function createLink(header) {
var innerText = (header.textContent === undefined) ? header.innerText : header.textContent;
var innerText = header.textContent || header.innerText;
return "<a class='" + settings.classes.link + "' href='#" + fixedEncodeURIComponent(header.id) + "'>" + innerText + "</a>";
}

var headers = $(settings.headers).filter(function () {
// get all headers with an ID
var previousSiblingName = $(this).prev().attr("name");
if (!this.id && previousSiblingName) {
this.id = $(this).attr("id", previousSiblingName.replace(/\./g, "-"));
// Ensure headers have IDs
if (!this.id) {
this.id = $(this).text().trim().replace(/\s+/g, '-').toLowerCase();
}
return this.id;
}), output = $(this);
});

var output = $(this);

// Check if there are any headers
if (!headers.length || headers.length < settings.minimumHeaders || !output.length) {

$('#main').removeClass("add-grid");
$("#toc").hide();
return; // Exit early if there are no headers
}

if (0 === settings.showSpeed) {
if (settings.showSpeed === 0) {
settings.showEffect = 'none';
}

$(this).addClass(settings.classes.toc)
$(this).addClass(settings.classes.toc);

var render = {
show: function () { output.hide().html(html).show(settings.showSpeed); },
Expand All @@ -61,47 +60,28 @@

var get_level = function (ele) { return parseInt(ele.nodeName.replace("H", ""), 10); };
var highest_level = headers.map(function (_, ele) { return get_level(ele); }).get().sort()[0];
var return_to_top = '<i class="icon-arrow-up back-to-top"> </i>';
var level = get_level(headers[0]), this_level;
var html = settings.title + " <" + settings.listType + " class=\"" + settings.classes.list + "\">";

var level = get_level(headers[0]),
this_level,
html = settings.title + " <" + settings.listType + " class=\"" + settings.classes.list + "\">";
headers.on('click', function () {
if (!settings.noBackToTopLinks) {
window.location.hash = this.id;
}
})
.addClass('clickable-header')
.each(function (_, header) {
this_level = get_level(header);
if (!settings.noBackToTopLinks && this_level === highest_level) {
$(header).addClass('top-level-header').after(return_to_top);
headers.each(function (_, header) {
this_level = get_level(header);
if (this_level === level) { // same level as before; same indenting
html += "<li class=\"" + settings.classes.item + "\">" + createLink(header);
} else if (this_level <= level) { // higher level than before; end parent ol
for (var i = this_level; i < level; i++) {
html += "</li></" + settings.listType + ">"
}
if (this_level === level) // same level as before; same indenting
html += "<li class=\"" + settings.classes.item + "\">" + createLink(header);
else if (this_level <= level) { // higher level than before; end parent ol
for (var i = this_level; i < level; i++) {
html += "</li></" + settings.listType + ">"
}
html += "<li class=\"" + settings.classes.item + "\">" + createLink(header);
html += "<li class=\"" + settings.classes.item + "\">" + createLink(header);
} else if (this_level > level) { // lower level than before; expand the previous to contain a ol
for (i = this_level; i > level; i--) {
html += "<" + settings.listType + " class=\"" + settings.classes.list + "\">" +
"<li class=\"" + settings.classes.item + "\">"
}
else if (this_level > level) { // lower level than before; expand the previous to contain a ol
for (i = this_level; i > level; i--) {
html += "<" + settings.listType + " class=\"" + settings.classes.list + "\">" +
"<li class=\"" + settings.classes.item + "\">"
}
html += createLink(header);
}
level = this_level; // update for the next one
});
html += createLink(header);
}
level = this_level; // update for the next one
});
html += "</" + settings.listType + ">";
if (!settings.noBackToTopLinks) {
$(document).on('click', '.back-to-top', function () {
$(window).scrollTop(0);
window.location.hash = '';
});
}

render[settings.showEffect]();
};
})(jQuery);
})(jQuery);

0 comments on commit 4b6f6bc

Please sign in to comment.