2026-10-27 TUE UTC 5:36 AM TPE 1:36 PM 每小時自動更新 中文 EN
LIVE快訊
←返回網站更新紀錄 Site Changelog

提交原始紀錄

Replay team mark when scrolled into view (#411)

SHA
85cc0e235b9fffb48a4e252ad66ca8f48402445f
提交時間
作者
neo · 125815713+nnneeeooo-nnneeeooo@users.noreply.github.com
提交者
GitHub · noreply@github.com

變更檔案(2)

  • static/team-logo.js modified · +18 / −15
  • tests/test_team_logo.js modified · +7 / −10

完整差異

diff --git a/static/team-logo.js b/static/team-logo.js\nindex ebca80a0a..ec27bfe95 100644\n--- a/static/team-logo.js\n+++ b/static/team-logo.js\n@@ -8,7 +8,14 @@\n   var reduced = window.matchMedia("(prefers-reduced-motion: reduce)");\n   var timer = 0;\n   var entryTimer = 0;\n-  var observer = null;\n+  var visibilityListener = null;\n+\n+  function stopWaiting() {\n+    if (!visibilityListener) return;\n+    window.removeEventListener("scroll", visibilityListener);\n+    window.removeEventListener("resize", visibilityListener);\n+    visibilityListener = null;\n+  }\n \n   function play(restart) {\n     if (reduced.matches || document.documentElement.dataset.theme === "8bit") return;\n@@ -34,23 +41,19 @@\n       if (image) image.addEventListener("load", function () { startOnEntry(event); }, { once: true });\n       return;\n     }\n-    if (observer) observer.disconnect();\n+    stopWaiting();\n     window.clearTimeout(entryTimer);\n     entryTimer = window.setTimeout(function () {\n-      var box = trigger.getBoundingClientRect();\n-      var inView = box.bottom > 0 && box.right > 0 &&\n-        box.top < window.innerHeight && box.left < window.innerWidth;\n-      if (inView) { play(Boolean(event.persisted)); return; }\n-      if ("IntersectionObserver" in window) {\n-        observer = new IntersectionObserver(function (entries) {\n-          if (!entries.some(function (entry) { return entry.isIntersecting; })) return;\n-          observer.disconnect();\n-          play(Boolean(event.persisted));\n-        }, { threshold: .6 });\n-        observer.observe(trigger);\n-      } else {\n+      visibilityListener = function () {\n+        var box = trigger.getBoundingClientRect();\n+        if (box.bottom <= 0 || box.right <= 0 ||\n+            box.top >= window.innerHeight || box.left >= window.innerWidth) return;\n+        stopWaiting();\n         play(Boolean(event.persisted));\n-      }\n+      };\n+      window.addEventListener("scroll", visibilityListener, { passive: true });\n+      window.addEventListener("resize", visibilityListener);\n+      visibilityListener();\n     }, 350);\n   }\n \ndiff --git a/tests/test_team_logo.js b/tests/test_team_logo.js\nindex f920c3258..c2445cb8c 100644\n--- a/tests/test_team_logo.js\n+++ b/tests/test_team_logo.js\n@@ -11,12 +11,12 @@ function setup(theme = "light", prefersReducedMotion = false, initiallyVisible =\n   const timers = new Map();\n   const listeners = {};\n   let nextTimer = 0;\n-  let observer;\n+  let visible = initiallyVisible;\n   const image = { complete: true, naturalWidth: 250 };\n   const trigger = {\n     offsetWidth: 88,\n     getBoundingClientRect() {\n-      return initiallyVisible\n+      return visible\n         ? { top: 718, bottom: 800, left: 24, right: 107 }\n         : { top: 900, bottom: 982, left: 24, right: 107 };\n     },\n@@ -28,17 +28,14 @@ function setup(theme = "light", prefersReducedMotion = false, initiallyVisible =\n     addEventListener(name, handler) { listeners[name] = handler; },\n     querySelector() { return image; },\n   };\n-  class IntersectionObserver {\n-    constructor(callback) { this.callback = callback; observer = this; }\n-    observe() {}\n-    disconnect() {}\n-  }\n   const window = {\n-    IntersectionObserver,\n     innerWidth: 390,\n     innerHeight: 844,\n     matchMedia() { return { matches: prefersReducedMotion }; },\n     addEventListener(name, handler) { listeners[name] = handler; },\n+    removeEventListener(name, handler) {\n+      if (listeners[name] === handler) delete listeners[name];\n+    },\n     setTimeout(handler) { const id = ++nextTimer; timers.set(id, handler); return id; },\n     clearTimeout(id) { timers.delete(id); },\n   };\n@@ -46,7 +43,7 @@ function setup(theme = "light", prefersReducedMotion = false, initiallyVisible =\n     documentElement: { dataset: { theme } },\n     querySelector() { return trigger; },\n   };\n-  vm.runInNewContext(source, { window, document, IntersectionObserver });\n+  vm.runInNewContext(source, { window, document });\n   return {\n     classes, listeners,\n     enter(persisted = false) {\n@@ -56,7 +53,7 @@ function setup(theme = "light", prefersReducedMotion = false, initiallyVisible =\n       timers.delete(first);\n       handler();\n     },\n-    reveal() { observer.callback([{ isIntersecting: true }]); },\n+    reveal() { visible = true; listeners.scroll(); },\n     finish() {\n       for (const handler of timers.values()) handler();\n       timers.clear();

你發現了隱藏主題!

8-bit主題已解鎖。 按下「重新整理」就會直接套用,之後可隨時在主題選單切換。