Fix thread scrubber anchoring
This commit is contained in:
parent
7b80afbd6c
commit
997184cd66
2 changed files with 19 additions and 5 deletions
|
|
@ -64,10 +64,11 @@
|
||||||
// The main column is its own scroll container (overflow-y-auto) and persists
|
// The main column is its own scroll container (overflow-y-auto) and persists
|
||||||
// across navigations, so SvelteKit's window-only scroll restoration never
|
// across navigations, so SvelteKit's window-only scroll restoration never
|
||||||
// resets it. Scroll it back to top on forward navigation; leave back/forward
|
// resets it. Scroll it back to top on forward navigation; leave back/forward
|
||||||
// (popstate) alone so returning to a listing keeps its place.
|
// (popstate) alone so returning to a listing keeps its place, and hash
|
||||||
|
// targets (#post-…) alone so the page can place the anchored post itself.
|
||||||
let mainEl = $state<HTMLElement | null>(null);
|
let mainEl = $state<HTMLElement | null>(null);
|
||||||
afterNavigate((nav) => {
|
afterNavigate((nav) => {
|
||||||
if (nav.type !== "popstate") mainEl?.scrollTo(0, 0);
|
if (nav.type !== "popstate" && !nav.to?.url.hash) mainEl?.scrollTo(0, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Nothing is fetched until the relay confirms it will serve this visitor:
|
// Nothing is fetched until the relay confirms it will serve this visitor:
|
||||||
|
|
|
||||||
|
|
@ -390,12 +390,25 @@
|
||||||
await quotePost(post, text);
|
await quotePost(post, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The scrubber sticks where the OP starts. Measure independently of the
|
||||||
|
// current scroll (the page may mount already scrolled, e.g. arriving from a
|
||||||
|
// profile with a reply link) and again when the header changes height.
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!opEl) return;
|
const el = opEl;
|
||||||
|
const header = threadEl?.querySelector("[data-thread-header]");
|
||||||
|
if (!el || !header) return;
|
||||||
const main = document.querySelector("main");
|
const main = document.querySelector("main");
|
||||||
if (!main) return;
|
if (!main) return;
|
||||||
opTopOffset =
|
const measure = () => {
|
||||||
opEl.getBoundingClientRect().top - main.getBoundingClientRect().top;
|
opTopOffset =
|
||||||
|
el.getBoundingClientRect().top -
|
||||||
|
main.getBoundingClientRect().top +
|
||||||
|
main.scrollTop;
|
||||||
|
};
|
||||||
|
measure();
|
||||||
|
const ro = new ResizeObserver(measure);
|
||||||
|
ro.observe(header);
|
||||||
|
return () => ro.disconnect();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue