pane-wrapper: switching views scrolls the pane column, never the embedding page

scrollTo(paneId) called target.scrollIntoView(), which scrolls every scrollable
ancestor, the embedding page included. On another site, "Map" / "Show on map"
moved the host's own page so that the map's top met the window's top, and a host
shorter than the window then showed its white space under the map. The column
is the scroller (position:absolute; overflow-y:auto) and each pane's
offsetParent, so col.scrollTo({ top: target.offsetTop }) lands the pane exactly
and leaves the page alone.
This commit is contained in:
Doxa Maps 2026-10-02 09:32:00 +00:00
parent cf0146775b
commit fc3ea94af8

View file

@ -172,9 +172,14 @@ export function buildPaneColumn(spec, { host, mountPane }) {
return {
panes: column,
/** Animate to a pane by id — this is what the View fieldset tabs call. */
// ★ SCROLL THE COLUMN, NEVER THE PAGE. scrollIntoView() scrolls EVERY scrollable ancestor, the embedding
// page included: on another site, "Map" / "Show on map" moved the host's own page so the map's top met the
// window's top, and a host shorter than the window then showed its white space under the map. The column is
// the scroller (position:absolute; overflow-y:auto) and each pane's offsetParent, so its offsetTop is exactly
// the scroll position that puts the pane at the top.
scrollTo(paneId) {
const target = col.querySelector(`.pane[data-pane-id="${paneId}"]`)
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' })
if (target) col.scrollTo({ top: target.offsetTop, behavior: 'smooth' })
},
/** Which pane is currently filling the viewport (for URL sync). */
current() {