diff options
author | amazingrise <8315221+AmazingRise@users.noreply.github.com> | 2020-07-13 18:07:04 +0300 |
---|---|---|
committer | amazingrise <8315221+AmazingRise@users.noreply.github.com> | 2020-07-13 18:07:04 +0300 |
commit | df3b6684610d783fdd7f2525da1c31f3a9349ca3 (patch) | |
tree | 8275942e29b35ec9f3f5e6c7dceac1dccf08bb29 /static | |
parent | 248b6008b45ee9af2dcbdc6e8af9285c3eb9f2e8 (diff) |
Fix #54
Diffstat (limited to 'static')
-rw-r--r-- | static/js/toc-collapse.js | 383 |
1 files changed, 197 insertions, 186 deletions
diff --git a/static/js/toc-collapse.js b/static/js/toc-collapse.js index 8af46b9..fa51778 100644 --- a/static/js/toc-collapse.js +++ b/static/js/toc-collapse.js @@ -1,57 +1,69 @@ var spy = function () { - var elems = $(":header"); - if (elems.length == 0) { - return; + var elems = $(":header"); + if (elems.length == 0) { + return; + } + var currentTop = $(window).scrollTop(); + var currentBottom = $(window).scrollTop() + $(window).height(); + var pageBottom = $('#EOF').offset().top; + + var meetUnread = false + var currentIndex = elems.length - 1 + elems.each(function (idx) { + var elemTop = $(this).offset().top; + var id = $(this).attr('id'); + var navElem = $('#' + id + '-nav'); + if (currentTop + $(this).height() >= elemTop) { + navElem.addClass('toc-active'); + } else { + if (meetUnread == false) { + meetUnread = true + currentIndex = idx - 1 + } + navElem.removeClass('toc-active'); } - var currentTop = $(window).scrollTop(); - var currentBottom = $(window).scrollTop() + $(window).height(); - var pageBottom = $('#EOF').offset().top; - - var meetUnread = false - var currentIndex = -1 - elems.each(function (idx) { - var elemTop = $(this).offset().top; - var id = $(this).attr('id'); - var navElem = $('#' + id + '-nav'); - if (currentTop + $(this).height() >= elemTop || currentBottom >= pageBottom) { - navElem.addClass('toc-active'); - } else { - if (meetUnread == false) { - meetUnread = true - currentIndex = idx - 1 - } - navElem.removeClass('toc-active'); - } - }) - //console.log(elems[currentIndex].id); - //Collapse them - collapseOthers(currentIndex); + }) + if (currentBottom >= pageBottom) { + currentIndex = -1 + } + //console.log(currentIndex); + //Collapse them + collapseOthers(currentIndex); } - - -var collapseOthers = function (currentIndex) { - if (currentIndex == -1) { - $(".collapse").each(function (idx) { - $(this).collapse("hide"); - }); +var onNavClick = function (name) { + var elems = $(":header"); + elems.each(function (idx) { + var id = $(this).attr('id'); + if (name == '#' + id + '-nav'){ + collapseOthers(idx); return; } - var elems = $(":header"); - currentId = "#" + elems[currentIndex].id + "-nav"; - //console.log(currentId); - - $(currentId).parents(".collapse").each(function (idx) { - $(this).collapse("show"); - }); - $(currentId).parent().next().filter(".collapse").collapse("show"); - $(".collapse").not($(currentId).parents()).not($(currentId).parent().next()).each(function (idx) { - $(this).collapse("hide"); + }); +} + +var collapseOthers = function (currentIndex) { + if (currentIndex == -1) { + $(".collapse").each(function (idx) { + $(this).collapse("hide"); }); + return; + } + var elems = $(":header"); + //console.log(currentIndex); + currentId = "#" + elems[currentIndex].id + "-nav"; + + $(currentId).parents(".collapse").each(function (idx) { + $(this).collapse("show"); + }); + $(currentId).parent().next().filter(".collapse").collapse("show"); + $(".collapse").not($(currentId).parents()).not($(currentId).parent().next()).each(function (idx) { + $(this).collapse("hide"); + }); } $().ready(function () { - spy(); - $(window).bind('scroll', debounce(spy, 250, { 'maxWait': 1000 })); + spy(); + $(window).bind('scroll', debounce(spy, 250, { 'maxWait': 1000 })); }); @@ -59,155 +71,154 @@ $().ready(function () { // and https://github.com/lodash/lodash/blob/master/isObject.js function debounce(func, wait, options) { - let lastArgs, - lastThis, - maxWait, - result, - timerId, - lastCallTime - - let lastInvokeTime = 0 - let leading = false - let maxing = false - let trailing = true - - // Bypass `requestAnimationFrame` by explicitly setting `wait=0`. - const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function') - - if (typeof func !== 'function') { - throw new TypeError('Expected a function') - } - function isObject(value) { - const type = typeof value - return value != null && (type === 'object' || type === 'function') - } + let lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime - wait = +wait || 0 - if (isObject(options)) { - leading = !!options.leading - maxing = 'maxWait' in options - maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait - trailing = 'trailing' in options ? !!options.trailing : trailing - } - - function invokeFunc(time) { - const args = lastArgs - const thisArg = lastThis - - lastArgs = lastThis = undefined - lastInvokeTime = time - result = func.apply(thisArg, args) - return result - } - - function startTimer(pendingFunc, wait) { - if (useRAF) { - root.cancelAnimationFrame(timerId) - return root.requestAnimationFrame(pendingFunc) - } - return setTimeout(pendingFunc, wait) - } - - function cancelTimer(id) { - if (useRAF) { - return root.cancelAnimationFrame(id) - } - clearTimeout(id) - } - - function leadingEdge(time) { - // Reset any `maxWait` timer. - lastInvokeTime = time - // Start the timer for the trailing edge. - timerId = startTimer(timerExpired, wait) - // Invoke the leading edge. - return leading ? invokeFunc(time) : result - } - - function remainingWait(time) { - const timeSinceLastCall = time - lastCallTime - const timeSinceLastInvoke = time - lastInvokeTime - const timeWaiting = wait - timeSinceLastCall - - return maxing - ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) - : timeWaiting - } - - function shouldInvoke(time) { - const timeSinceLastCall = time - lastCallTime - const timeSinceLastInvoke = time - lastInvokeTime - - // Either this is the first call, activity has stopped and we're at the - // trailing edge, the system time has gone backwards and we're treating - // it as the trailing edge, or we've hit the `maxWait` limit. - return (lastCallTime === undefined || (timeSinceLastCall >= wait) || - (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)) - } - - function timerExpired() { - const time = Date.now() - if (shouldInvoke(time)) { - return trailingEdge(time) - } - // Restart the timer. - timerId = startTimer(timerExpired, remainingWait(time)) + let lastInvokeTime = 0 + let leading = false + let maxing = false + let trailing = true + + // Bypass `requestAnimationFrame` by explicitly setting `wait=0`. + const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function') + + if (typeof func !== 'function') { + throw new TypeError('Expected a function') + } + function isObject(value) { + const type = typeof value + return value != null && (type === 'object' || type === 'function') + } + + wait = +wait || 0 + if (isObject(options)) { + leading = !!options.leading + maxing = 'maxWait' in options + maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait + trailing = 'trailing' in options ? !!options.trailing : trailing + } + + function invokeFunc(time) { + const args = lastArgs + const thisArg = lastThis + + lastArgs = lastThis = undefined + lastInvokeTime = time + result = func.apply(thisArg, args) + return result + } + + function startTimer(pendingFunc, wait) { + if (useRAF) { + root.cancelAnimationFrame(timerId) + return root.requestAnimationFrame(pendingFunc) } - - function trailingEdge(time) { - timerId = undefined - - // Only invoke if we have `lastArgs` which means `func` has been - // debounced at least once. - if (trailing && lastArgs) { - return invokeFunc(time) - } - lastArgs = lastThis = undefined - return result + return setTimeout(pendingFunc, wait) + } + + function cancelTimer(id) { + if (useRAF) { + return root.cancelAnimationFrame(id) } - - function cancel() { - if (timerId !== undefined) { - cancelTimer(timerId) - } - lastInvokeTime = 0 - lastArgs = lastCallTime = lastThis = timerId = undefined + clearTimeout(id) + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time + // Start the timer for the trailing edge. + timerId = startTimer(timerExpired, wait) + // Invoke the leading edge. + return leading ? invokeFunc(time) : result + } + + function remainingWait(time) { + const timeSinceLastCall = time - lastCallTime + const timeSinceLastInvoke = time - lastInvokeTime + const timeWaiting = wait - timeSinceLastCall + + return maxing + ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting + } + + function shouldInvoke(time) { + const timeSinceLastCall = time - lastCallTime + const timeSinceLastInvoke = time - lastInvokeTime + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)) + } + + function timerExpired() { + const time = Date.now() + if (shouldInvoke(time)) { + return trailingEdge(time) } - - function flush() { - return timerId === undefined ? result : trailingEdge(Date.now()) + // Restart the timer. + timerId = startTimer(timerExpired, remainingWait(time)) + } + + function trailingEdge(time) { + timerId = undefined + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time) } - - function pending() { - return timerId !== undefined + lastArgs = lastThis = undefined + return result + } + + function cancel() { + if (timerId !== undefined) { + cancelTimer(timerId) } - - function debounced(...args) { - const time = Date.now() - const isInvoking = shouldInvoke(time) - - lastArgs = args - lastThis = this - lastCallTime = time - - if (isInvoking) { - if (timerId === undefined) { - return leadingEdge(lastCallTime) - } - if (maxing) { - // Handle invocations in a tight loop. - timerId = startTimer(timerExpired, wait) - return invokeFunc(lastCallTime) - } - } + lastInvokeTime = 0 + lastArgs = lastCallTime = lastThis = timerId = undefined + } + + function flush() { + return timerId === undefined ? result : trailingEdge(Date.now()) + } + + function pending() { + return timerId !== undefined + } + + function debounced(...args) { + const time = Date.now() + const isInvoking = shouldInvoke(time) + + lastArgs = args + lastThis = this + lastCallTime = time + + if (isInvoking) { if (timerId === undefined) { + return leadingEdge(lastCallTime) + } + if (maxing) { + // Handle invocations in a tight loop. timerId = startTimer(timerExpired, wait) + return invokeFunc(lastCallTime) } - return result } - debounced.cancel = cancel - debounced.flush = flush - debounced.pending = pending - return debounced + if (timerId === undefined) { + timerId = startTimer(timerExpired, wait) + } + return result } -
\ No newline at end of file + debounced.cancel = cancel + debounced.flush = flush + debounced.pending = pending + return debounced +} |