From 950994b56985a67ba1eb72d73604a3563550619e Mon Sep 17 00:00:00 2001 From: ImXiangYu <2670833123@qq.com> Date: Mon, 9 Mar 2026 23:48:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E9=80=82=E9=85=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- better-github-nav.user.js | 52 +++++++++++++++++++++++---------------- package-lock.json | 4 +-- package.json | 2 +- src/navigation.js | 44 ++++++++++++++++++++++++--------- src/styles.js | 11 ++------- 5 files changed, 68 insertions(+), 45 deletions(-) diff --git a/better-github-nav.user.js b/better-github-nav.user.js index 6dc6b31..6d498a2 100644 --- a/better-github-nav.user.js +++ b/better-github-nav.user.js @@ -2,7 +2,7 @@ // @name Better GitHub Navigation // @name:zh-CN 更好的 GitHub 导航栏 // @namespace https://github.com/ImXiangYu/better-github-nav -// @version 0.1.44 +// @version 0.1.45 // @description Bring Dashboard, Trending, Explore, Collections, and Stars closer on desktop and narrow screens, and keep your most-used repositories pinned where they are easiest to reach. // @description:zh-CN 在桌面端和窄屏场景下,把 Dashboard、Trending、Explore、Collections、Stars 放到更顺手的位置,并把你最常用的仓库固定在最容易到达的地方。 // @author Ayubass @@ -16,7 +16,7 @@ (() => { // src/constants.js - var SCRIPT_VERSION = "0.1.44"; + var SCRIPT_VERSION = "0.1.45"; var CUSTOM_BUTTON_CLASS = "custom-gh-nav-btn"; var CUSTOM_BUTTON_ACTIVE_CLASS = "custom-gh-nav-btn-active"; var CUSTOM_BUTTON_COMPACT_CLASS = "custom-gh-nav-btn-compact"; @@ -242,8 +242,8 @@ transform: rotate(180deg); } .custom-gh-nav-overflow-menu { - position: absolute; - top: calc(100% + 8px); + position: fixed; + top: 0; left: 0; z-index: 2147483646; display: flex; @@ -545,13 +545,6 @@ margin: 6px 0; background: var(--color-border-muted, rgba(208, 215, 222, 0.8)); } - @media (max-width: 767px) { - .custom-gh-nav-overflow-menu { - left: auto; - right: 0; - min-width: min(240px, calc(100vw - 16px)); - } - } `; document.head.appendChild(style); } @@ -723,18 +716,29 @@ state.toggleButton.setAttribute("aria-expanded", state.menuOpen ? "true" : "false"); } function positionResponsiveQuickLinksMenu(state) { - state.menuNode.style.left = "0"; - state.menuNode.style.right = "auto"; - const rect = state.menuNode.getBoundingClientRect(); const viewportPadding = 8; - if (rect.right > window.innerWidth - viewportPadding) { - state.menuNode.style.left = "auto"; - state.menuNode.style.right = "0"; - } - if (state.menuNode.getBoundingClientRect().left < viewportPadding) { - state.menuNode.style.left = "0"; - state.menuNode.style.right = "auto"; + const anchorRect = state.toggleButton.getBoundingClientRect(); + state.menuNode.style.left = `${viewportPadding}px`; + state.menuNode.style.top = `${Math.round(anchorRect.bottom + viewportPadding)}px`; + const menuRect = state.menuNode.getBoundingClientRect(); + const maxLeft = Math.max(viewportPadding, window.innerWidth - menuRect.width - viewportPadding); + const preferredLeft = anchorRect.right - menuRect.width; + const fallbackLeft = anchorRect.left; + const unclampedLeft = preferredLeft >= viewportPadding ? preferredLeft : fallbackLeft; + const left = Math.min(maxLeft, Math.max(viewportPadding, unclampedLeft)); + let top = anchorRect.bottom + viewportPadding; + const fitsBelow = top + menuRect.height <= window.innerHeight - viewportPadding; + const fitsAbove = anchorRect.top - viewportPadding - menuRect.height >= viewportPadding; + if (!fitsBelow && fitsAbove) { + top = anchorRect.top - viewportPadding - menuRect.height; + } else if (!fitsBelow) { + top = Math.max( + viewportPadding, + window.innerHeight - menuRect.height - viewportPadding + ); } + state.menuNode.style.left = `${Math.round(left)}px`; + state.menuNode.style.top = `${Math.round(top)}px`; } function closeResponsiveQuickLinksMenu() { const state = responsiveQuickLinksState; @@ -742,6 +746,7 @@ hideHotkeyTooltip(); state.menuOpen = false; state.menuNode.hidden = true; + state.menuNode.style.visibility = ""; updateResponsiveQuickLinksToggle(state); } function toggleResponsiveQuickLinksMenu() { @@ -751,7 +756,9 @@ state.menuOpen = !state.menuOpen; state.menuNode.hidden = !state.menuOpen; if (state.menuOpen) { + state.menuNode.style.visibility = "hidden"; positionResponsiveQuickLinksMenu(state); + state.menuNode.style.visibility = ""; } updateResponsiveQuickLinksToggle(state); } @@ -852,6 +859,9 @@ if (target && state.toggleHostNode.contains(target)) return; closeResponsiveQuickLinksMenu(); }, true); + document.addEventListener("scroll", () => { + closeResponsiveQuickLinksMenu(); + }, true); } function setupResponsiveQuickLinks({ renderParent, diff --git a/package-lock.json b/package-lock.json index 9b13766..760921f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "better-github-nav", - "version": "0.1.44", + "version": "0.1.45", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "better-github-nav", - "version": "0.1.44", + "version": "0.1.45", "license": "MIT", "devDependencies": { "esbuild": "^0.27.3" diff --git a/package.json b/package.json index deefba4..4753421 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "better-github-nav", - "version": "0.1.44", + "version": "0.1.45", "description": "Bring Dashboard, Trending, Explore, Collections, and Stars closer on desktop and narrow screens, and keep your most-used repositories pinned where they are easiest to reach.", "private": true, "scripts": { diff --git a/src/navigation.js b/src/navigation.js index 92541b4..ab7a568 100644 --- a/src/navigation.js +++ b/src/navigation.js @@ -194,20 +194,33 @@ function updateResponsiveQuickLinksToggle(state) { } function positionResponsiveQuickLinksMenu(state) { - state.menuNode.style.left = '0'; - state.menuNode.style.right = 'auto'; - - const rect = state.menuNode.getBoundingClientRect(); const viewportPadding = 8; - - if (rect.right > window.innerWidth - viewportPadding) { - state.menuNode.style.left = 'auto'; - state.menuNode.style.right = '0'; - } - if (state.menuNode.getBoundingClientRect().left < viewportPadding) { - state.menuNode.style.left = '0'; - state.menuNode.style.right = 'auto'; + const anchorRect = state.toggleButton.getBoundingClientRect(); + + state.menuNode.style.left = `${viewportPadding}px`; + state.menuNode.style.top = `${Math.round(anchorRect.bottom + viewportPadding)}px`; + + const menuRect = state.menuNode.getBoundingClientRect(); + const maxLeft = Math.max(viewportPadding, window.innerWidth - menuRect.width - viewportPadding); + const preferredLeft = anchorRect.right - menuRect.width; + const fallbackLeft = anchorRect.left; + const unclampedLeft = preferredLeft >= viewportPadding ? preferredLeft : fallbackLeft; + const left = Math.min(maxLeft, Math.max(viewportPadding, unclampedLeft)); + + let top = anchorRect.bottom + viewportPadding; + const fitsBelow = top + menuRect.height <= window.innerHeight - viewportPadding; + const fitsAbove = anchorRect.top - viewportPadding - menuRect.height >= viewportPadding; + if (!fitsBelow && fitsAbove) { + top = anchorRect.top - viewportPadding - menuRect.height; + } else if (!fitsBelow) { + top = Math.max( + viewportPadding, + window.innerHeight - menuRect.height - viewportPadding + ); } + + state.menuNode.style.left = `${Math.round(left)}px`; + state.menuNode.style.top = `${Math.round(top)}px`; } function closeResponsiveQuickLinksMenu() { @@ -217,6 +230,7 @@ function closeResponsiveQuickLinksMenu() { hideHotkeyTooltip(); state.menuOpen = false; state.menuNode.hidden = true; + state.menuNode.style.visibility = ''; updateResponsiveQuickLinksToggle(state); } @@ -228,7 +242,9 @@ function toggleResponsiveQuickLinksMenu() { state.menuOpen = !state.menuOpen; state.menuNode.hidden = !state.menuOpen; if (state.menuOpen) { + state.menuNode.style.visibility = 'hidden'; positionResponsiveQuickLinksMenu(state); + state.menuNode.style.visibility = ''; } updateResponsiveQuickLinksToggle(state); } @@ -354,6 +370,10 @@ function bindResponsiveQuickLinksGlobalHandlers() { if (target && state.toggleHostNode.contains(target)) return; closeResponsiveQuickLinksMenu(); }, true); + + document.addEventListener('scroll', () => { + closeResponsiveQuickLinksMenu(); + }, true); } function setupResponsiveQuickLinks({ diff --git a/src/styles.js b/src/styles.js index 1442c3f..dc278f8 100644 --- a/src/styles.js +++ b/src/styles.js @@ -74,8 +74,8 @@ export function ensureStyles() { transform: rotate(180deg); } .custom-gh-nav-overflow-menu { - position: absolute; - top: calc(100% + 8px); + position: fixed; + top: 0; left: 0; z-index: 2147483646; display: flex; @@ -377,13 +377,6 @@ export function ensureStyles() { margin: 6px 0; background: var(--color-border-muted, rgba(208, 215, 222, 0.8)); } - @media (max-width: 767px) { - .custom-gh-nav-overflow-menu { - left: auto; - right: 0; - min-width: min(240px, calc(100vw - 16px)); - } - } `; document.head.appendChild(style); }