Jump to content
Search Community

Issue with ScrollTrigger and Changing Routes on Static Site Generators / Frontend Frameworks?

JayLow test
Moderator Tag

Recommended Posts

Hello,

Lately I've been facing an issue which has been very hard for me to debug. I've been using Nuxt to build a static site and scrolltrigger for some of the animations. When changing routes, I face an issue of some reused components not having the right top/bottom trigger amount, and the site keeping its scroll position on a route change when it should go back to the top . Resizing fixes the first issue, but I cannot solve the second. 

I've noticed many cases of similar occuring on similar frameworks

Quote

 

 

Quote

 

Quote
Quote

 

Anyways, I wanted to see if this is a known issue with the framework or GSAP? All my components kill their scrolltrigger instance on a route change, so garbage cleanup is fine. I've tried downgrading nuxt to no evail either, but it doesn't seem like a nuxt problem because it looks to be happening regardless of framework? The only thing that works for the wrong trigger amount is calling scrolltrigger.refresh() after an arbitary amount of time, but thats not really a fix. Anyways just look for any advice on what from those who have faced similar or to see if the issue is known. 

Link to comment
Share on other sites

Are you using the latest version (3.7.1)? I'd definitely make sure you're on the latest version as step 1 - that will likely fix the scroll position thing.

 

As for calling ScrollTrigger.refresh() after an arbitrary amount of time, that definitely sounds like a framework-related issue or something on your end - basically, you need to make sure ScrollTrigger.refresh() gets called when all your elements are loaded and done messing with the layout so that it can calculate start/end positions based on where everything is located. Perhaps you need to tap into a lifecycle method in your framework that signals when everything is finished loading and layout isn't shifting around. 

 

If you still need help, feel free to post a minimal demo - that always gives you the best chance of getting an accurate answer. 👍

 

Thanks for being a Club GreenSock member! 🙌

Link to comment
Share on other sites

Just seconding this - if you could create a minimal demo on codesandbox that would be hugely helpful.

 

We get a lot of requests for help on this but no one's put together simplified demo that we can actually take a look at yet. Most of the time the issue is down to other complex things happening - hydration/image loading

 

If you can show an example where a simple route change and ScrollTrigger.refresh() is not working, that would be wonderful - it would be great to get to the bottom of the scroll position issue once and for all!

However it is usually to do with calling ScrollTrigger.refresh() before layout shifts/lazy loading/DOM renders have occurred. All frameworks have different ways of handling this so it's down to the developer to find that out and refresh accordingly!

Link to comment
Share on other sites

On 8/22/2021 at 3:45 PM, JayLow said:

I've been using Nuxt to build a static site and scrolltrigger for some of the animations. When changing routes, I face an issue of some reused components not having the right top/bottom trigger amount, and the site keeping its scroll position on a route change when it should go back to the top .

 

Nuxt won't automatically scroll to the top on child routes.

https://nuxtjs.org/docs/2.x/components-glossary/pages-scrolltotop

 

2 hours ago, Sanjero said:

My page is a simple HTML/CSS not React, Angular, etc. But I have same issue when I refresh the page.

 

Browsers save the scroll position when you reload a page. Try it without adding scroll trigger, and it should reload to its last scroll position.

 

Link to comment
Share on other sites

46 minutes ago, OSUblake said:

Browsers save the scroll position when you reload a page. Try it without adding scroll trigger, and it should reload to its last scroll position.

 

 

That's correct but how can I solve this issue? is this possible for ScrollTrigger to read the saved scroll position?

Link to comment
Share on other sites

27 minutes ago, OSUblake said:

Works for me. What did you try?

 

Yes, works for the browser to not saving the scroll position but not for GSAP.

 

I used:

 

if (history.scrollRestoration) {
  history.scrollRestoration = "manual";
else {
  window.onbeforeunload = function () {
    window.scrollTo(00);
  };
}
Link to comment
Share on other sites

@OSUblake @GreenSock @Cassie


Been digging into this more lately. I setup a listener to see when the window.scrollTo() is invoked to see precisely what is happening. My Vue instance is scrolling to (0,0) as intended on a route change. When the route changes, the new ScrollTrigger instances are created as expected. However, all of these new instances immedietely call the window.scrollTo method, which shoots the page downward to a much lower position (in this case 0 , 9408). So the default vue scroll to top is being overriden by scrolltrigger scrolling way down when a new class is setup. 

 

 

 

I commented out the ability for scrolltrigger to call window.scrollTo in its source file. This has solved the issue temporarily, but is obviously not the best way haha. 

What is attached to Scrolltrigger that would cause it to invoke window.scrollTo when a new class is created?

Link to comment
Share on other sites

32 minutes ago, JayLow said:

What is attached to Scrolltrigger that would cause it to invoke window.scrollTo when a new class is created?

I'm not sure I follow your question - did you mean when a new ScrollTrigger instance is created? 

 

ScrollTrigger must record the scroll position in order to function properly. Let's say, for example, your page is natively 1000px tall but you set up a ScrollTrigger to pin an element for 2000px. That means that technically the page would become 3000px tall. When you refresh the browser window, ScrollTrigger must revert everything (remove all the pinning) so that things are back in their natural state so styles are applied properly and measurements are accurate. It all must flow from top to bottom measurement-wise. So let's say your viewport is 600px tall and you scroll down 800px and then refresh...note that's further than the native page even allows (1000px native - 600px viewport = 400px maximum scroll). You'd jump to a different position on refresh in that case if ScrollTrigger didn't remember (and revert) the scroll position. There are several other scenarios where that could happen. So yeah, this is an important feature. 

 

We added code in 3.7.1, though, so if you kill all you ScrollTrigger instances it will also flush the scroll position memory, so I'm a bit confused about why you're seeing that behavior. Again, it's super-duper tough to diagnose blind unfortunately. 

 

Oh, and you mentioned jQuery causing problems - GSAP works fantastically with jQuery. Zero conflicts whatsoever, at least I've never in my life seen any and I know for sure that hundreds of thousands of sites use them together. I wonder if you've got some kind of funky jQuery plugin that's interfering with the scroll stuff? I'm totally guessing there. 🤷‍♂️

 

You don't have scroll-behavior: smooth anywhere, do you? I've seen that cause problems. 

  • Like 2
Link to comment
Share on other sites

On 9/2/2021 at 1:14 AM, GreenSock said:

I'm not sure I follow your question - did you mean when a new ScrollTrigger instance is created? 

 

ScrollTrigger must record the scroll position in order to function properly. Let's say, for example, your page is natively 1000px tall but you set up a ScrollTrigger to pin an element for 2000px. That means that technically the page would become 3000px tall. When you refresh the browser window, ScrollTrigger must revert everything (remove all the pinning) so that things are back in their natural state so styles are applied properly and measurements are accurate. It all must flow from top to bottom measurement-wise. So let's say your viewport is 600px tall and you scroll down 800px and then refresh...note that's further than the native page even allows (1000px native - 600px viewport = 400px maximum scroll). You'd jump to a different position on refresh in that case if ScrollTrigger didn't remember (and revert) the scroll position. There are several other scenarios where that could happen. So yeah, this is an important feature. 

 

We added code in 3.7.1, though, so if you kill all you ScrollTrigger instances it will also flush the scroll position memory, so I'm a bit confused about why you're seeing that behavior. Again, it's super-duper tough to diagnose blind unfortunately. 

 

Oh, and you mentioned jQuery causing problems - GSAP works fantastically with jQuery. Zero conflicts whatsoever, at least I've never in my life seen any and I know for sure that hundreds of thousands of sites use them together. I wonder if you've got some kind of funky jQuery plugin that's interfering with the scroll stuff? I'm totally guessing there. 🤷‍♂️

 

You don't have scroll-behavior: smooth anywhere, do you? I've seen that cause problems. 

Hi Sorry for the late response.

Thanks for the explanation (and apologies for not being able to get you a demo). Maybe something in Nuxt is causing things to go out of order? It's odd because the jump happens after the page url has changed. This is the part of code I commented out in ScrollTrigger.js that fixed the issue. It hasnt seemed to have caused issues anywhere else, so I suppose I'll leave it for the time being.

 

 sc: function sc(value) {
    return arguments.length ? /*_win.scrollTo(_horizontal.sc(), value)*/ '' : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0;
  }

and
 

sc: function sc(value) {
    return arguments.length ? /*_win.scrollTo(value, _vertical.sc())*/ '' : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0;
  }


Also no smooth scroll behavior or jquery for me. 
 

Link to comment
Share on other sites

Yeah, I wouldn't recommend doing that. It will break certain scenarios where it needs to retain the scroll position after a refresh() and snapping won't work at all (at least on the window). 

 

If you are using 3.7.1 or later and you make sure you kill() all ScrollTrigger instances when you navigate to a new URL, you should be fine. I suspect you forgot to do at least one of those things. If you're still having trouble, please provide a minimal demo and we'd be glad to take a peek. 

Link to comment
Share on other sites

2 hours ago, JayLow said:

Maybe something in Nuxt is causing things to go out of order?

 

Do your pages have transitions on them? Nuxt changes the scroll position after the transition is complete, which will usually happen after your onMounted, which I'm assuming is where you are creating your scroll triggers.

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...