This issue is isolated to Safari on macOS and iOS. All other browsers don’t have this problem.
I have an Intersection Observer that handles loading/unloading chapters in a vertical scrolling book.
This function unloads chapters that aren’t in view:
function unloadChapter(chapterId) {
const chapterElement = document.querySelector('.chapter[data-chapter-id="' + chapterId + '"] .chapter-content');
if (chapterElement) {
chapterElement.innerHTML = '';
}
}
When unloading a chapter below the current position, there’s no scroll jank.
But when unloading a chapter above the current chapter, the scroll position jumps due to the sudden unload of content, but only on Safari.
I have a temporary work around by adding back in the difference of lost content height, then scrolling back to the new relative position:
function unloadChapter(chapterId) {
const chapterElement = document.querySelector('.chapter[data-chapter-id="' + chapterId + '"] .chapter-content');
if (chapterElement) {
// Measure the current scroll height
const previousScrollHeight = document.documentElement.scrollHeight;
// Measure the current scroll position
const previousScrollTop = window.scrollY || document.documentElement.scrollTop;
// Unload the chapter content
chapterElement.innerHTML = '';
// Measure the new scroll height after unloading the content
const newScrollHeight = document.documentElement.scrollHeight;
// Calculate the difference in scroll height
const scrollHeightDifference = previousScrollHeight - newScrollHeight;
// Adjust the scroll position based on the difference in height
window.scrollTo(0, previousScrollTop - scrollHeightDifference);
}
}
But this causes a noticeable flicker when scrolling.