Skip to content

Commit 721201b

Browse files
committed
Fix bounce
1 parent 7d6083d commit 721201b

File tree

1 file changed

+32
-73
lines changed

1 file changed

+32
-73
lines changed

src/components/Header.astro

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,13 @@ document.addEventListener("DOMContentLoaded", function() {
7070
navbar.style.transition = "transform 0.3s ease-in-out";
7171

7272
function updateNavbar() {
73-
const currentScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
74-
const documentHeight = document.documentElement.scrollHeight;
75-
const windowHeight = window.innerHeight;
76-
77-
// Don't hide navbar when at the very top - increased threshold for reliability
78-
if (currentScrollPos <= 20) {
73+
// Handle iOS bounce - scroll position can be negative during bounce
74+
const rawScrollPos = window.pageYOffset || document.documentElement.scrollTop;
75+
const currentScrollPos = Math.max(0, rawScrollPos);
76+
77+
// Show navbar immediately if we're bouncing above the page (negative scroll)
78+
// or if we're very close to the top
79+
if (rawScrollPos <= 0 || currentScrollPos <= 50) {
7980
if (!isVisible) {
8081
navbar.style.transform = "translateY(0)";
8182
isVisible = true;
@@ -85,8 +86,11 @@ document.addEventListener("DOMContentLoaded", function() {
8586
return;
8687
}
8788

89+
const documentHeight = document.documentElement.scrollHeight;
90+
const windowHeight = window.innerHeight;
91+
8892
// Don't hide navbar when at the very bottom
89-
if (currentScrollPos + windowHeight >= documentHeight - 10) {
93+
if (currentScrollPos + windowHeight >= documentHeight - 50) {
9094
if (!isVisible) {
9195
navbar.style.transform = "translateY(0)";
9296
isVisible = true;
@@ -96,9 +100,9 @@ document.addEventListener("DOMContentLoaded", function() {
96100
return;
97101
}
98102

99-
// Only update if scroll difference is significant (helps with iOS bounce)
103+
// Only update if scroll difference is significant
100104
const scrollDiff = Math.abs(currentScrollPos - prevScrollPos);
101-
if (scrollDiff < 5) {
105+
if (scrollDiff < 3) {
102106
ticking = false;
103107
return;
104108
}
@@ -107,7 +111,7 @@ document.addEventListener("DOMContentLoaded", function() {
107111
if (prevScrollPos > currentScrollPos && !isVisible) {
108112
navbar.style.transform = "translateY(0)";
109113
isVisible = true;
110-
} else if (prevScrollPos < currentScrollPos && isVisible) {
114+
} else if (prevScrollPos < currentScrollPos && isVisible && currentScrollPos > 100) {
111115
navbar.style.transform = "translateY(-100%)";
112116
isVisible = false;
113117
}
@@ -116,89 +120,44 @@ document.addEventListener("DOMContentLoaded", function() {
116120
ticking = false;
117121
}
118122

119-
// Additional polling check when near the top (for edge cases)
120-
let topCheckInterval: any = null;
121-
122-
function startTopCheck() {
123-
if (topCheckInterval) return;
124-
topCheckInterval = setInterval(() => {
125-
const currentScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
126-
if (currentScrollPos <= 20 && !isVisible) {
127-
navbar.style.transform = "translateY(0)";
128-
isVisible = true;
129-
prevScrollPos = currentScrollPos;
130-
}
131-
if (currentScrollPos > 100 && topCheckInterval) {
132-
clearInterval(topCheckInterval);
133-
topCheckInterval = null;
134-
}
135-
}, 50);
136-
}
137-
138123
function requestTick() {
139124
if (!ticking) {
140125
requestAnimationFrame(updateNavbar);
141126
ticking = true;
142127
}
143-
144-
// Start polling when we're in the danger zone
145-
const currentScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
146-
if (currentScrollPos <= 100) {
147-
startTopCheck();
148-
}
149128
}
150129

151130
// Use passive listener for better performance on mobile
152131
window.addEventListener("scroll", requestTick, { passive: true });
153132

154-
// Handle keyboard navigation (arrow keys, page up/down, home/end)
155-
document.addEventListener("keydown", function(e) {
156-
const keysToWatch = ['PageUp', 'PageDown', 'End', 'Home', 'ArrowUp', 'ArrowDown'];
157-
if (keysToWatch.includes(e.key)) {
158-
setTimeout(() => {
159-
const currentScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
160-
if (currentScrollPos <= 10) {
161-
navbar.style.transform = "translateY(0)";
162-
isVisible = true;
163-
prevScrollPos = currentScrollPos;
164-
}
165-
}, 100);
166-
}
167-
});
168-
169-
// Additional check with a longer delay for keyboard scrolling
170-
document.addEventListener("keyup", function(e) {
171-
const keysToWatch = ['PageUp', 'PageDown', 'End', 'Home', 'ArrowUp', 'ArrowDown'];
172-
if (keysToWatch.includes(e.key)) {
173-
setTimeout(() => {
174-
const currentScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
175-
if (currentScrollPos <= 10) {
176-
navbar.style.transform = "translateY(0)";
177-
isVisible = true;
178-
prevScrollPos = currentScrollPos;
179-
}
180-
}, 200);
133+
// Additional safety check specifically for iOS bounce recovery
134+
let bounceCheckTimeout: any = null;
135+
136+
window.addEventListener("scroll", function() {
137+
// Clear any existing timeout
138+
if (bounceCheckTimeout) {
139+
clearTimeout(bounceCheckTimeout);
181140
}
182-
});
183-
184-
// Handle orientation change on mobile devices
185-
window.addEventListener("orientationchange", function() {
186-
setTimeout(() => {
187-
prevScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
188-
if (prevScrollPos <= 10) {
141+
142+
// Set a timeout to check position after scroll momentum stops
143+
bounceCheckTimeout = setTimeout(() => {
144+
const finalScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
145+
if (finalScrollPos <= 50 && !isVisible) {
189146
navbar.style.transform = "translateY(0)";
190147
isVisible = true;
148+
prevScrollPos = finalScrollPos;
191149
}
192-
}, 100);
193-
});
150+
}, 150);
151+
}, { passive: true });
194152

195153
// Handle page visibility changes (when switching tabs/apps)
196154
document.addEventListener("visibilitychange", function() {
197155
if (!document.hidden) {
198-
prevScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
199-
if (prevScrollPos <= 10) {
156+
const currentScrollPos = Math.max(0, window.pageYOffset || document.documentElement.scrollTop);
157+
if (currentScrollPos <= 50) {
200158
navbar.style.transform = "translateY(0)";
201159
isVisible = true;
160+
prevScrollPos = currentScrollPos;
202161
}
203162
}
204163
});

0 commit comments

Comments
 (0)