FIX: CLS jumpiness in post-stream when ?page=N (#25034)
With certain conditions, this issue does not show up. The easiest way to reproduce this is probably to do either of this - Use a 3G slow connection or; - Add a breakpoint to scrolling-post-stream.topRefresh (anon) - (and optionally lock-on.lock) This issue is happening because there are multiple areas that set scroll location in the post stream when loading a topic. In our case, sometimes lock-on is triggering and scrolling to post_1, before ?page=2's post_21 is being scrolled to, due to posts above post_21 can finishing loading at different times. This causes some calculations to not add up, as being in the middle of a post stream has different calculations than being at the top of the post stream.
This commit is contained in:
parent
bf3e121323
commit
12131c8e21
|
@ -181,10 +181,7 @@ export default MountWidget.extend({
|
|||
const first = posts.objectAt(onscreen[0]);
|
||||
if (this._topVisible !== first) {
|
||||
this._topVisible = first;
|
||||
const elem = postsNodes.item(onscreen[0]);
|
||||
const elemId = elem.id;
|
||||
const elemPos = domUtils.position(elem);
|
||||
const distToElement = elemPos?.top || 0;
|
||||
const elemId = postsNodes.item(onscreen[0]).id;
|
||||
|
||||
const topRefresh = () => {
|
||||
refresh(() => {
|
||||
|
@ -194,16 +191,30 @@ export default MountWidget.extend({
|
|||
return;
|
||||
}
|
||||
|
||||
const position = domUtils.position(refreshedElem);
|
||||
const top = position.top - distToElement;
|
||||
document.documentElement.scroll({ top, left: 0 });
|
||||
// The getOffsetTop function calculates the total offset distance of
|
||||
// an element from the top of the document. Unlike element.offsetTop
|
||||
// which only returns the offset relative to its nearest positioned
|
||||
// ancestor, this function recursively accumulates the offsetTop
|
||||
// of an element and all of its offset parents (ancestors).
|
||||
// This ensures the total distance is measured from the very top of
|
||||
// the document, accounting for any nested elements and their
|
||||
// respective offsets.
|
||||
const getOffsetTop = (element) => {
|
||||
if (!element) {
|
||||
return 0;
|
||||
}
|
||||
return element.offsetTop + getOffsetTop(element.offsetParent);
|
||||
};
|
||||
|
||||
const top = getOffsetTop(refreshedElem) - offsetCalculator();
|
||||
window.scrollTo({ top });
|
||||
|
||||
// This seems weird, but somewhat infrequently a rerender
|
||||
// will cause the browser to scroll to the top of the document
|
||||
// in Chrome. This makes sure the scroll works correctly if that
|
||||
// happens.
|
||||
schedule("afterRender", () => {
|
||||
document.documentElement.scroll({ top, left: 0 });
|
||||
window.scrollTo({ top });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue