Gsap ScrollTrigger and a click event using scrollTop highlighting menu items

I've a menu where each item corresponds to a section div. Click on an item, it adds a border-bottom, and scrolls somewhere vaguely near the element (because life, and scroll-padding, just can't be that easy). Simple stuff. But then I've added ScrollTrigger to track which section I'm above when scrolling and change the active menu item accordingly. This unfortunately means that when you click a menu item, say item 4, it now scrolls to 4, but highlights menu items 1,2,3 and then 4 on the way there. Just wondering how people would approach this, because at the moment my solutions feel a bit hacky. Eg: I'm considering disabling ScrollTrigger quickly after the click event, and then listening for a scrollend event to re enable it, or making the border-bottom transparent. There's a property to prevent animations overlapping: preventOverlaps but I've either implemented it wrong or it doesn't disable the callbacks (onEnter etc). Just think there must be a better solution I haven't thought of. Here's a codepen šŸ™‚ https://codepen.io/nwoodward/pen/NWBmZgd?editors=0011
21 Replies
b1mind
b1mindā€¢2y ago
I disable scroll-behavior: smooth or rather don't use it when I have this case, I don't like the motion on anchor tags personally šŸ˜® ah but how you have things set up I guess it would still roll through each. šŸ¤”
JWode
JWodeOPā€¢2y ago
I was hoping you'd see this šŸ˜
b1mind
b1mindā€¢2y ago
Yea I'm semi sidetracks but I have quesitons
JWode
JWodeOPā€¢2y ago
Yeah, I just knew the client (my friend) would love it
b1mind
b1mindā€¢2y ago
First you arnt using anchors šŸ˜„ Like Nav > with no ahrefs servs no purpose, not good practice for nav when you have access to actual anchors Don't lean to heavy on JS till you need too Leverage the native API ScrollIntoView I think always "scrolls" with motion So the Preferred reduced motion and css smooth scrollyou have get skipped in this case.
JWode
JWodeOPā€¢2y ago
Nah, I think ScrollIntoView jumps directly there without scroll-behavior: smooth; doesn't it? also, 'whoops' on the a tags šŸ˜„ so i should be able to ditch scrollintoview. but that doesn't fix my issue if i want to keep the scroll effect, does it?
b1mind
b1mindā€¢2y ago
You have to pass the object to tell it in js element.scrollIntoView({behavior: "smooth", block: "end", inline: "nearest"}) o maybe reverse idk I can't seem to changes it behavior. To the point though use a real nav > ahrefs with anchor tags, period Even if its not a solution to start its the right start Also yes it should also skip scrollTrigger events though (cause it is going to snap right to the anchor)
JWode
JWodeOPā€¢2y ago
yeah will do. this is my first time using scrolling like this so didn't really consider that would work really, that's interesting, but it will still scroll down the page? i'll give it a try now thanks
b1mind
b1mindā€¢2y ago
only with scroll-behavior: smooth
JWode
JWodeOPā€¢2y ago
yeah that's what i'm currently using nice, ill try it
b1mind
b1mindā€¢2y ago
again you would be utilizing that where as now I don't think that currently works with what you ahve now cause you are using JS to scroll, with scrollIntoView() šŸ˜‰
JWode
JWodeOPā€¢2y ago
feels weird that scroll trigger won't pick that up, but I'm not going to argue if it works!
b1mind
b1mindā€¢2y ago
idk ScrollIntoView() support is weak cause Safari options it looks like and I think if you were to use scrollTo() it does not act the same Before Safari 15.4, there was no support for the smooth behavior. Like don't even look like safari support the options object for it Either way use the platform and make better html navigation. Its a better start, then enhance that You can also leverage scroll-margin-top in css if you use anchors https://codepen.io/b1mind/pen/bGVemWx (you can also disable the scroll-behavior here and see how it snaps not scrolls)
JWode
JWodeOPā€¢2y ago
ah, are you telling me that scroll-margin-top wasn't working because I was using JS šŸ˜† , well that's 1 issue fixed! cool demo, thanks a tags do seem to trigger scrolltrigger though, annoyingly (have updated my pen)
b1mind
b1mindā€¢2y ago
Ok but now least you have a good start
JWode
JWodeOPā€¢2y ago
yeah true, and scroll-padding being ignored was on my to-do list, so thanks! padding/margin
b1mind
b1mindā€¢2y ago
Another sidenote would be using Sticky if you can for the nav vs fixed. It will save that space in the dom for the first section not to sit under (if you have that issue) sticky does have its limits and gotchas though
JWode
JWodeOPā€¢2y ago
yeah, I've a class I use for that first section šŸ˜† I'll give sticky a shot
b1mind
b1mindā€¢2y ago
So yea if you remove the scroll-behavior now it should snap right to the section too and not animated through. If you still wanted the smooth scroll you are going to have to come up with different logic to toggle that class or use a timeline to animate inand out of maybe. My brains still a bit fogged after the past few weeks so drawing a blank how I would do it.
JWode
JWodeOPā€¢2y ago
it does, you're correct. probably a nicer effect for the time being until i can work out an alternative approach. I'm surprised calling .disable() on all the ScrollTrigger objects didn't work:
toggle() {
if(this._menuScrollTrigger) {
this._menuScrollTrigger = false;

this._sectionTriggers.forEach(trigger => {
trigger.disable()
})
} else {
this._menuScrollTrigger = true;
this._sectionTriggers.forEach(trigger => {
trigger.enable()
})
}
toggle() {
if(this._menuScrollTrigger) {
this._menuScrollTrigger = false;

this._sectionTriggers.forEach(trigger => {
trigger.disable()
})
} else {
this._menuScrollTrigger = true;
this._sectionTriggers.forEach(trigger => {
trigger.enable()
})
}
I need to look into it further, because I reckon I was calling toggle(); ele.scrollTop({...}); toggle() which thinking about it wouldn't wait for the scrolling to take place, so maybe it actually was working and I need to call the second toggle when there's a scrollend event... I'll let you know how I get on! (also, hope the last few weeks have been nothing worse than busy!)
Want results from more Discord servers?
Add your server