Capture the scroll element in its effect so teardown does not read a cleared binding

This commit is contained in:
Coracle-Bot 2026-09-10 03:21:27 +00:00 committed by hodlbod
parent 68dd74d1fd
commit fa5a9f6a1e
3 changed files with 16 additions and 10 deletions

View file

@ -11,8 +11,10 @@
$effect(() => {
if (!element) return
const target = element
const update = () => {
const {scrollTop, scrollHeight, clientHeight} = element as HTMLElement
const {scrollTop, scrollHeight, clientHeight} = target as HTMLElement
const scrollable = scrollHeight - clientHeight
// A non-scrollable page reads as zero rather than a misleading full bar.
@ -21,19 +23,19 @@
update()
element.addEventListener("scroll", update, {passive: true})
target.addEventListener("scroll", update, {passive: true})
// Content (article, then comments) keeps arriving after mount, resizing the scroll range.
const observer = new ResizeObserver(update)
observer.observe(element)
observer.observe(target)
for (const child of element.children) {
for (const child of target.children) {
observer.observe(child)
}
return () => {
element.removeEventListener("scroll", update)
target.removeEventListener("scroll", update)
observer.disconnect()
}
})

View file

@ -12,14 +12,16 @@
$effect(() => {
if (element) {
const target = element
const onScroll = () => {
scrolled = element.scrollTop > 800
scrolled = target.scrollTop > 800
}
element.addEventListener("scroll", onScroll, {passive: true})
target.addEventListener("scroll", onScroll, {passive: true})
onScroll()
return () => element.removeEventListener("scroll", onScroll)
return () => target.removeEventListener("scroll", onScroll)
}
})
</script>

View file

@ -91,9 +91,11 @@
$effect(() => {
if (container) {
container.addEventListener("scroll", fill, {passive: true})
const target = container
return () => container.removeEventListener("scroll", fill)
target.addEventListener("scroll", fill, {passive: true})
return () => target.removeEventListener("scroll", fill)
}
})
</script>