123 lines
3.8 KiB
JavaScript
123 lines
3.8 KiB
JavaScript
|
//= require ../lib/_jquery
|
|||
|
//= require ../lib/_imagesloaded.min
|
|||
|
;(function () {
|
|||
|
'use strict';
|
|||
|
|
|||
|
var htmlPattern = /<[^>]*>/g;
|
|||
|
var loaded = false;
|
|||
|
|
|||
|
var debounce = function(func, waitTime) {
|
|||
|
var timeout = false;
|
|||
|
return function() {
|
|||
|
if (timeout === false) {
|
|||
|
setTimeout(function() {
|
|||
|
func();
|
|||
|
timeout = false;
|
|||
|
}, waitTime);
|
|||
|
timeout = true;
|
|||
|
}
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
var closeToc = function() {
|
|||
|
$(".toc-wrapper").removeClass('open');
|
|||
|
$("#nav-button").removeClass('open');
|
|||
|
};
|
|||
|
|
|||
|
function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) {
|
|||
|
var headerHeights = {};
|
|||
|
var pageHeight = 0;
|
|||
|
var windowHeight = 0;
|
|||
|
var originalTitle = document.title;
|
|||
|
|
|||
|
var recacheHeights = function() {
|
|||
|
headerHeights = {};
|
|||
|
pageHeight = $(document).height();
|
|||
|
windowHeight = $(window).height();
|
|||
|
|
|||
|
$toc.find(tocLinkSelector).each(function() {
|
|||
|
var targetId = $(this).attr('href');
|
|||
|
if (targetId[0] === "#") {
|
|||
|
headerHeights[targetId] = $("#" + $.escapeSelector(targetId.substring(1))).offset().top;
|
|||
|
}
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
var refreshToc = function() {
|
|||
|
var currentTop = $(document).scrollTop() + scrollOffset;
|
|||
|
|
|||
|
if (currentTop + windowHeight >= pageHeight) {
|
|||
|
// at bottom of page, so just select last header by making currentTop very large
|
|||
|
// this fixes the problem where the last header won't ever show as active if its content
|
|||
|
// is shorter than the window height
|
|||
|
currentTop = pageHeight + 1000;
|
|||
|
}
|
|||
|
|
|||
|
var best = null;
|
|||
|
for (var name in headerHeights) {
|
|||
|
if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) {
|
|||
|
best = name;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Catch the initial load case
|
|||
|
if (currentTop == scrollOffset && !loaded) {
|
|||
|
best = window.location.hash;
|
|||
|
loaded = true;
|
|||
|
}
|
|||
|
|
|||
|
var $best = $toc.find("[href='" + best + "']").first();
|
|||
|
if (!$best.hasClass("active")) {
|
|||
|
// .active is applied to the ToC link we're currently on, and its parent <ul>s selected by tocListSelector
|
|||
|
// .active-expanded is applied to the ToC links that are parents of this one
|
|||
|
$toc.find(".active").removeClass("active");
|
|||
|
$toc.find(".active-parent").removeClass("active-parent");
|
|||
|
$best.addClass("active");
|
|||
|
$best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent');
|
|||
|
$best.siblings(tocListSelector).addClass("active");
|
|||
|
$toc.find(tocListSelector).filter(":not(.active)").slideUp(150);
|
|||
|
$toc.find(tocListSelector).filter(".active").slideDown(150);
|
|||
|
if (window.history.replaceState) {
|
|||
|
window.history.replaceState(null, "", best);
|
|||
|
}
|
|||
|
var thisTitle = $best.data("title");
|
|||
|
if (thisTitle !== undefined && thisTitle.length > 0) {
|
|||
|
document.title = thisTitle.replace(htmlPattern, "") + " – " + originalTitle;
|
|||
|
} else {
|
|||
|
document.title = originalTitle;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
var makeToc = function() {
|
|||
|
recacheHeights();
|
|||
|
refreshToc();
|
|||
|
|
|||
|
$("#nav-button").click(function() {
|
|||
|
$(".toc-wrapper").toggleClass('open');
|
|||
|
$("#nav-button").toggleClass('open');
|
|||
|
return false;
|
|||
|
});
|
|||
|
$(".page-wrapper").click(closeToc);
|
|||
|
$(".toc-link").click(closeToc);
|
|||
|
|
|||
|
// reload immediately after scrolling on toc click
|
|||
|
$toc.find(tocLinkSelector).click(function() {
|
|||
|
setTimeout(function() {
|
|||
|
refreshToc();
|
|||
|
}, 0);
|
|||
|
});
|
|||
|
|
|||
|
$(window).scroll(debounce(refreshToc, 200));
|
|||
|
$(window).resize(debounce(recacheHeights, 200));
|
|||
|
};
|
|||
|
|
|||
|
makeToc();
|
|||
|
|
|||
|
window.recacheHeights = recacheHeights;
|
|||
|
window.refreshToc = refreshToc;
|
|||
|
}
|
|||
|
|
|||
|
window.loadToc = loadToc;
|
|||
|
})();
|