Hi,
I’ve attached a demo of the .pin-spacer causing a jump animation on mobile when i scroll upward on mobile devices. It works smoothly on desktop.
iOS Safari has a feature that results in window.innerHeight providing different values based on whether or not the URL control and menu bar are expanded.
Link to Demo
codesandbox.io
I didn’t use codepen because it puts the demo in an iframe. It wouldn’t be able to reproduce the bug on mobile.
Link to Video
iOS Bug
In the video, you can see the inline height and padding styles of the .pin-spacer are changing based on the direction I'm scrolling.
How to Reproduce
Go to my demo on an iOS device or the simulator on a mac
Scroll down a bit, stop, and then scroll a little in the opposite direction to allow the navigation to reappear.
Device - iPhone 12 Pro running iOS 15.4
What I’ve Tried:
I’ve tried updating the .pin-spacer height and padding within the onUpdate method of the ScrollTrigger, but GSAP library still fires its sendResize function.
I’ve also read these threads that said this issue is caused by rendering and the main thread being handled differently on mobile - but I think its caused by the safe area.
Layered Pinning Bug
Pin Spacer Height on Mobile
ScrollTrigger Jumping
Assumption
In the GSAP codebase, the functions below are fired when the inline styles of the .pin-spacer are updated. The navigation/menu expanding because of scrolling on iOS could be causing a browser event that is continuously firing getDocumentHeight() - which will update the .pin-spacer with the wrong values.
function getDocumentHeight() {
const { body } = document;
const html = document.documentElement;
return Math.max(body.scrollHeight, body.offsetHeight, html.offsetHeight);
}
function sendResize() {
const height = getDocumentHeight();
if (lastHeight !== height) {
dispatch({ type: 'resize', height });
}
lastHeight = height;
}
function initializeDOMMutationListener() {
if (
typeof window === 'undefined' ||
typeof window.MutationObserver !== 'function'
) {
return;
}
// Listen on document body for any change that could trigger a resize of the content
// When a change is found, the sendResize function will determine if a message is dispatched
const observer = new MutationObserver(sendResize);
observer.observe(document, {
attributes: true,
childList: true,
subtree: true,
});
window.addEventListener('unload', () => {
observer.disconnect();
});
}
Any help would be greatly appreciated!