From 9d657b0e5a16bd83d88163b586b647a5c9d50a4a Mon Sep 17 00:00:00 2001 From: FlintyLemming Date: Mon, 19 Jan 2026 12:03:19 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=87=92=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/hugo-theme-stack/assets/ts/main.ts | 31 ------------------- .../hugo-theme-stack/assets/ts/scrollspy.ts | 31 +++++++++++-------- .../partials/footer/components/script.html | 2 -- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/themes/hugo-theme-stack/assets/ts/main.ts b/themes/hugo-theme-stack/assets/ts/main.ts index f3160ae..95c7f65 100644 --- a/themes/hugo-theme-stack/assets/ts/main.ts +++ b/themes/hugo-theme-stack/assets/ts/main.ts @@ -6,7 +6,6 @@ * @link: https://github.com/CaiJimmy/hugo-theme-stack */ import StackGallery from "ts/gallery"; -import { getColor } from 'ts/color'; import menu from 'ts/menu'; import createElement from 'ts/createElement'; import StackColorScheme from 'ts/colorScheme'; @@ -27,36 +26,6 @@ let Stack = { setupScrollspy(); } - /** - * Add linear gradient background to tile style article - */ - const articleTile = document.querySelector('.article-list--tile'); - if (articleTile) { - let observer = new IntersectionObserver(async (entries, observer) => { - entries.forEach(entry => { - if (!entry.isIntersecting) return; - observer.unobserve(entry.target); - - const articles = entry.target.querySelectorAll('article.has-image'); - articles.forEach(async articles => { - const image = articles.querySelector('img'), - imageURL = image.src, - key = image.getAttribute('data-key'), - hash = image.getAttribute('data-hash'), - articleDetails: HTMLDivElement = articles.querySelector('.article-details'); - - const colors = await getColor(key, hash, imageURL); - - articleDetails.style.background = ` - linear-gradient(0deg, - rgba(${colors.DarkMuted.rgb[0]}, ${colors.DarkMuted.rgb[1]}, ${colors.DarkMuted.rgb[2]}, 0.5) 0%, - rgba(${colors.Vibrant.rgb[0]}, ${colors.Vibrant.rgb[1]}, ${colors.Vibrant.rgb[2]}, 0.75) 100%)`; - }) - }) - }); - - observer.observe(articleTile) - } /** diff --git a/themes/hugo-theme-stack/assets/ts/scrollspy.ts b/themes/hugo-theme-stack/assets/ts/scrollspy.ts index 7cf416e..3e5d511 100644 --- a/themes/hugo-theme-stack/assets/ts/scrollspy.ts +++ b/themes/hugo-theme-stack/assets/ts/scrollspy.ts @@ -1,14 +1,19 @@ // Implements a scroll spy system for the ToC, displaying the current section with an indicator and scrolling to it when needed. -// Inspired from https://gomakethings.com/debouncing-your-javascript-events/ -function debounced(func: Function) { - let timeout; - return () => { - if (timeout) { - window.cancelAnimationFrame(timeout); - } +// Throttle function - limits execution to once per frame, with trailing call +function throttled(func: Function) { + let ticking = false; + let lastArgs: any = null; - timeout = window.requestAnimationFrame(() => func()); + return (...args: any[]) => { + lastArgs = args; + if (!ticking) { + ticking = true; + window.requestAnimationFrame(() => { + func.apply(null, lastArgs); + ticking = false; + }); + } } } @@ -74,8 +79,8 @@ function setupScrollspy() { // We need to avoid scrolling when the user is actively interacting with the ToC. Otherwise, if the user clicks on a link in the ToC, // we would scroll their view, which is not optimal usability-wise. let tocHovered: boolean = false; - scrollableNavigation.addEventListener("mouseenter", debounced(() => tocHovered = true)); - scrollableNavigation.addEventListener("mouseleave", debounced(() => tocHovered = false)); + scrollableNavigation.addEventListener("mouseenter", () => tocHovered = true, { passive: true }); + scrollableNavigation.addEventListener("mouseleave", () => tocHovered = false, { passive: true }); let activeSectionLink: Element; @@ -119,7 +124,7 @@ function setupScrollspy() { } } - window.addEventListener("scroll", debounced(scrollHandler)); + window.addEventListener("scroll", throttled(scrollHandler), { passive: true }); // Resizing may cause the offset values to change: recompute them. function resizeHandler() { @@ -130,11 +135,11 @@ function setupScrollspy() { // Use ResizeObserver to detect changes in the size of .article-content const articleContent = document.querySelector(".article-content"); if (articleContent) { - const resizeObserver = new ResizeObserver(debounced(resizeHandler)); + const resizeObserver = new ResizeObserver(throttled(resizeHandler)); resizeObserver.observe(articleContent); } - window.addEventListener("resize", debounced(resizeHandler)); + window.addEventListener("resize", throttled(resizeHandler), { passive: true }); } export { setupScrollspy }; diff --git a/themes/hugo-theme-stack/layouts/partials/footer/components/script.html b/themes/hugo-theme-stack/layouts/partials/footer/components/script.html index 3dc96cb..3d585b6 100644 --- a/themes/hugo-theme-stack/layouts/partials/footer/components/script.html +++ b/themes/hugo-theme-stack/layouts/partials/footer/components/script.html @@ -1,5 +1,3 @@ -{{- partial "helper/external" (dict "Context" . "Namespace" "Vibrant") -}} - {{- $opts := dict "minify" hugo.IsProduction -}} {{- $script := resources.Get "ts/main.ts" | js.Build $opts | fingerprint -}}