scroll_util: Account for $elem not direct child of scroll container.

When using `position` to get the scroll offset, it uses `offsetParent`
to calculate the offset which is not necessary the scroll container.

To account for this case, we use `offset` to correctly calculate
the position of element relative to the document.
This commit is contained in:
Aman Agrawal
2025-01-23 15:07:24 +05:30
committed by Tim Abbott
parent 25cb87cdc3
commit dd33ad11f5
2 changed files with 13 additions and 3 deletions

View File

@@ -77,7 +77,14 @@ export function scroll_element_into_container(
// this will be non-intrusive to users when they already have // this will be non-intrusive to users when they already have
// the element visible. // the element visible.
$container = get_scroll_element($container); $container = get_scroll_element($container);
const elem_top = $elem.position().top - sticky_header_height;
// To correctly compute the offset of the element's scroll
// position within our scroll container, we need to substract the
// scroll container's own offset within the document.
const elem_offset = $elem.offset()?.top ?? 0;
const container_offset = $container.offset()?.top ?? 0;
const elem_top = elem_offset - container_offset - sticky_header_height;
const elem_bottom = elem_top + ($elem.innerHeight() ?? 0); const elem_bottom = elem_top + ($elem.innerHeight() ?? 0);
const container_height = ($container.height() ?? 0) - sticky_header_height; const container_height = ($container.height() ?? 0) - sticky_header_height;

View File

@@ -96,13 +96,16 @@ run_test("scroll_element_into_container", () => {
top = arg; top = arg;
return this; return this;
}, },
offset: () => ({
top: 0,
}),
__zjquery: true, __zjquery: true,
}; };
})(); })();
const $elem1 = { const $elem1 = {
innerHeight: () => 25, innerHeight: () => 25,
position: () => ({ offset: () => ({
top: 0, top: 0,
}), }),
}; };
@@ -111,7 +114,7 @@ run_test("scroll_element_into_container", () => {
const $elem2 = { const $elem2 = {
innerHeight: () => 15, innerHeight: () => 15,
position: () => ({ offset: () => ({
top: 250, top: 250,
}), }),
}; };