diff options
author | amazingrise <8315221+AmazingRise@users.noreply.github.com> | 2021-05-14 09:17:46 +0300 |
---|---|---|
committer | amazingrise <8315221+AmazingRise@users.noreply.github.com> | 2021-05-14 09:17:46 +0300 |
commit | cc8287964b4d52b203f56efc87181dbbab42979e (patch) | |
tree | 414824d751a8e3703383ae9e2dac4ccb0ddfc96f /layouts | |
parent | 67dcd4949d63350f71fdbcfbbe75b8b581dc07b7 (diff) |
Change throttle to debounce.
Diffstat (limited to 'layouts')
-rw-r--r-- | layouts/partials/journal.html | 165 |
1 files changed, 153 insertions, 12 deletions
diff --git a/layouts/partials/journal.html b/layouts/partials/journal.html index ea7ee66..83b8041 100644 --- a/layouts/partials/journal.html +++ b/layouts/partials/journal.html @@ -60,18 +60,159 @@ app = new Vue({ document.body.classList.remove("night"); } }, - throttle(callback, limit) { - var wait = false; - return function (...args) { - if (!wait) { - callback(...args); - wait = true; - setTimeout(function () { - wait = false; - }, limit); + 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') + } + + 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)) + } + + 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 + } + + function cancel() { + if (timerId !== undefined) { + cancelTimer(timerId) + } + 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) + } + } + if (timerId === undefined) { + timerId = startTimer(timerExpired, wait) + } + return result + } + debounced.cancel = cancel + debounced.flush = flush + debounced.pending = pending + return debounced + } + }, created() { window.addEventListener('scroll', this.handleScroll); @@ -138,7 +279,7 @@ app = new Vue({ {{ if and (not (.Params.disableToC) ) (.IsPage) }} spy(); - window.addEventListener('wheel', this.throttle(spy,200), false); + window.addEventListener('wheel', this.debounce(spy, 250, { 'maxWait': 1000 }), false); {{ end }} }, @@ -148,6 +289,6 @@ app = new Vue({ } }); -new SmoothScroll('a#globalBackToTop'); +//new SmoothScroll('a#globalBackToTop'); </script>
\ No newline at end of file |