Skip to content

Commit 915000b

Browse files
authored
Fix crown not taking account sticky headers with smooth scrolling (#285)
1 parent 247a06d commit 915000b

File tree

1 file changed

+72
-39
lines changed

1 file changed

+72
-39
lines changed

src/content/actions/scroll.ts

+72-39
Original file line numberDiff line numberDiff line change
@@ -235,50 +235,83 @@ export function snapScroll(
235235
scrollAmount = isPageScroll ? -(cHeight - bottom) : -(cBottom - bottom);
236236
}
237237

238-
scrollContainer.scrollBy({
239-
left: 0,
240-
top: scrollAmount,
241-
behavior: getScrollBehavior(),
242-
});
238+
let stickyHeight = 0;
243239

244-
// Handle sticky headers
245240
if (position === "top") {
246-
let stickyFound: boolean;
247-
248-
// If we find a sticky element we scroll so that the top of our target
249-
// element coincides with the bottom of the sticky element. We keep doing
250-
// this in case there are stacked sticky elements
251-
do {
252-
stickyFound = false;
253-
const { x, y, top } = target.element.getBoundingClientRect();
254-
const elementsAtCoordinates = document.elementsFromPoint(x + 5, y + 5);
255-
256-
for (const element of elementsAtCoordinates) {
257-
if (element === target.element || element.contains(target.element)) {
258-
break;
259-
}
241+
// Retrieve possible sticky/fixed header height. This handles the cases where
242+
// the sticky/fixed header was in its final position before scrolling.
243+
const { x, y } = target.element.getBoundingClientRect();
244+
const elementsAtCoordinates = document.elementsFromPoint(
245+
x + 5,
246+
y - scrollAmount + 5
247+
);
260248

261-
const { position, display, visibility, opacity } =
262-
window.getComputedStyle(element);
263-
264-
if (
265-
display !== "none" &&
266-
visibility !== "hidden" &&
267-
opacity !== "0" &&
268-
(position === "sticky" || position === "fixed")
269-
) {
270-
const stickyBottom = element.getBoundingClientRect().bottom;
271-
scrollContainer.scrollBy({
272-
left: 0,
273-
top: top - stickyBottom,
274-
behavior: getScrollBehavior(),
275-
});
276-
stickyFound = true;
277-
break;
278-
}
249+
for (const element of elementsAtCoordinates) {
250+
if (element === target.element || element.contains(target.element)) {
251+
break;
252+
}
253+
254+
const { position, display, visibility, opacity } =
255+
window.getComputedStyle(element);
256+
257+
if (
258+
display !== "none" &&
259+
visibility !== "hidden" &&
260+
opacity !== "0" &&
261+
(position === "sticky" || position === "fixed")
262+
) {
263+
stickyHeight = element.getBoundingClientRect().height;
264+
break;
279265
}
280-
} while (stickyFound);
266+
}
267+
268+
// Handle the cases where the sticky header wasn't in its final position
269+
// before scrolling.
270+
(scrollContainer === document.documentElement
271+
? window
272+
: scrollContainer
273+
).addEventListener(
274+
"scrollend",
275+
() => {
276+
// If we find a sticky element we scroll so that the top of our target
277+
// element coincides with the bottom of the sticky element. We keep doing
278+
// this in case there are stacked sticky elements
279+
const { x, y, top } = target.element.getBoundingClientRect();
280+
const elementsAtCoordinates = document.elementsFromPoint(x + 5, y + 5);
281+
282+
for (const element of elementsAtCoordinates) {
283+
if (element === target.element || element.contains(target.element)) {
284+
break;
285+
}
286+
287+
const { position, display, visibility, opacity } =
288+
window.getComputedStyle(element);
289+
290+
if (
291+
display !== "none" &&
292+
visibility !== "hidden" &&
293+
opacity !== "0" &&
294+
(position === "sticky" || position === "fixed")
295+
) {
296+
const stickyBottom = element.getBoundingClientRect().bottom;
297+
scrollContainer.scrollBy({
298+
left: 0,
299+
top: top - stickyBottom,
300+
behavior: getScrollBehavior(),
301+
});
302+
break;
303+
}
304+
}
305+
},
306+
{ once: true }
307+
);
281308
}
309+
310+
scrollContainer.scrollBy({
311+
left: 0,
312+
top: scrollAmount - stickyHeight,
313+
behavior: getScrollBehavior(),
314+
});
282315
}
283316

284317
export function scroll(options: ScrollOptions) {

0 commit comments

Comments
 (0)