Fix footer freezing after Année filter / Aller à / retour à Toutes

v-if="loading" swaps out <div ref="tableWrap"> for a brand new DOM
node every time loading toggles true -> false. mounted() only attaches
the scroll listener once, to whichever wrap existed at mount time --
enterYearMode(), exitYearMode(), and jumpToYear() all trigger that
swap, silently orphaning the listener on the old (now-detached) node.
After any of those three, scrolling stopped calling checkEdges()/
detectCurrentYear() at all, freezing the footer's year totals.

ensureScrollListener() re-attaches (idempotently, via a dataset flag)
after every such transition. Verified: the wrap element does change
identity across jumpToYear(), and the new element picks up the
listener and fetches totals for the newly-visible year correctly.
This commit is contained in:
2026-09-04 21:39:19 +02:00
parent 53c4e58e72
commit a45d55cb81
@@ -605,6 +605,22 @@
this.checkEdges();
});
},
// mounted() only runs once, but `v-if="loading"` swaps out the
// <div ref="tableWrap"> for a fresh DOM node every time loading
// toggles true -> false (enterYearMode/exitYearMode/jumpToYear all
// do this) -- the old node's scroll listener goes with it, silently
// leaving the new one with no listener at all (checkEdges() and
// detectCurrentYear(), and so the footer, stop responding to
// scroll). Call this after every such transition, once the new
// wrap exists; the dataset flag makes it a no-op if the element is
// unchanged.
ensureScrollListener() {
const wrap = this.$refs.tableWrap;
if (wrap && !wrap.dataset.figliScrollBound) {
wrap.dataset.figliScrollBound = '1';
wrap.addEventListener('scroll', this.onScroll, { passive: true });
}
},
async loadCurrentYearTotals() {
if (!this.currentYear) return;
this.currentYearLoading = true;
@@ -638,6 +654,7 @@
}
await this.$nextTick();
if (this.$refs.tableWrap) this.$refs.tableWrap.scrollTop = 0;
this.ensureScrollListener();
this.detectCurrentYear();
},
// Back to "Toutes" -- resume the normal sliding window, re-centered
@@ -648,6 +665,7 @@
await this.$nextTick();
const wrap = this.$refs.tableWrap;
if (wrap) wrap.scrollTop = wrap.scrollHeight;
this.ensureScrollListener();
this.detectCurrentYear();
},
// "Aller à" -- a one-shot navigation shortcut, distinct from the
@@ -686,6 +704,7 @@
await this.$nextTick();
const wrap = this.$refs.tableWrap;
if (wrap) wrap.scrollTop = 0;
this.ensureScrollListener();
this.detectCurrentYear();
this.checkEdges();
},
@@ -713,8 +732,8 @@
jQuery(document).on('dialog:afterclose', () => this.reloadWindow());
await this.$nextTick();
const wrap = this.$refs.tableWrap;
this.ensureScrollListener();
if (wrap) {
wrap.addEventListener('scroll', this.onScroll, { passive: true });
// Start scrolled to the most recent data (the window is centered
// on "today", so that's the bottom of what's loaded).
wrap.scrollTop = wrap.scrollHeight;