108 lines
3.7 KiB
JavaScript
108 lines
3.7 KiB
JavaScript
(function() {
|
|
var SOURCES = window.TEXT_VARIABLES.sources;
|
|
window.Lazyload.js(SOURCES.jquery, function() {
|
|
function toc(options) {
|
|
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
|
|
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
|
|
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
|
|
|
|
function setOptions(options) {
|
|
var _options = options || {};
|
|
_options.selectors && (selectors = _options.selectors);
|
|
_options.container && (container = _options.container);
|
|
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
|
|
_options.scroller && (scroller = _options.scroller);
|
|
_options.disabled !== undefined && (disabled = _options.disabled);
|
|
$headings = $(container).find(selectors).filter('[id]');
|
|
$scrollTarget = $(scrollTarget);
|
|
$scroller = $(scroller);
|
|
}
|
|
function calc() {
|
|
headingsPos = [];
|
|
$headings.each(function() {
|
|
headingsPos.push(Math.floor($(this).position().top));
|
|
});
|
|
}
|
|
function setState(element, disabled) {
|
|
var scrollTop = $scrollTarget.scrollTop(), i;
|
|
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
|
|
if (element) {
|
|
$activeCur = element;
|
|
} else {
|
|
for (i = 0; i < headingsPos.length; i++) {
|
|
if (scrollTop >= headingsPos[i]) {
|
|
$activeCur = $tocLi.eq(i);
|
|
} else {
|
|
$activeCur || ($activeCur = $tocLi.eq(i));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
$activeLast && $activeLast.removeClass('active');
|
|
($activeLast = $activeCur).addClass('active');
|
|
}
|
|
function render() {
|
|
if(!hasRendered) {
|
|
$root.append($tocUl);
|
|
$headings.each(function() {
|
|
var $this = $(this);
|
|
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
|
|
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
|
|
});
|
|
$tocLi = $tocUl.children('li');
|
|
$tocUl.on('click', 'a', function(e) {
|
|
e.preventDefault();
|
|
var $this = $(this);
|
|
scrolling = true;
|
|
setState($this.parent());
|
|
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
|
|
scrolling = false;
|
|
});
|
|
});
|
|
}
|
|
hasRendered = true;
|
|
}
|
|
function init() {
|
|
var interval, timeout;
|
|
if(!hasInit) {
|
|
render(); calc(); setState(null, scrolling);
|
|
// run calc every 100 millisecond
|
|
interval = setInterval(function() {
|
|
calc();
|
|
}, 100);
|
|
timeout = setTimeout(function() {
|
|
clearInterval(interval);
|
|
}, 45000);
|
|
window.pageLoad.then(function() {
|
|
setTimeout(function() {
|
|
clearInterval(interval);
|
|
clearTimeout(timeout);
|
|
}, 3000);
|
|
});
|
|
$scrollTarget.on('scroll', function() {
|
|
disabled || setState(null, scrolling);
|
|
});
|
|
$window.on('resize', window.throttle(function() {
|
|
if (!disabled) {
|
|
render(); calc(); setState(null, scrolling);
|
|
}
|
|
}, 100));
|
|
}
|
|
hasInit = true;
|
|
}
|
|
|
|
setOptions(options);
|
|
if (!disabled) {
|
|
init();
|
|
}
|
|
$window.on('resize', window.throttle(function() {
|
|
init();
|
|
}, 200));
|
|
return {
|
|
setOptions: setOptions
|
|
};
|
|
}
|
|
$.fn.toc = toc;
|
|
});
|
|
})();
|