Jump to content
Search Community

Fixed sidebar menu moves when anchors are clicked

DilionS test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Hey everyone,

 

So as you'll see I have a sidebar menu that when you click on the anchors it scrolls to the section.

 

However the entire menu moves when you click on the anchor.

I'm imagining this might be caused by the fact the navigation bar is inside the scrollAreaWrapper and scrollContent div.

 

So either there is something I'm missing or I need to move the navigation somewhere else.

 

Any guidance or help would be appreciated.

 

Thank you,
Dilion Smith

See the Pen QWBPLzK by DilionsCode (@DilionsCode) on CodePen

Link to comment
Share on other sites

  • Solution

Hi,

 

There are a couple of issues with your example.

 

First you're not including and registering the ScrollTo Plugin, so that's not going to work. Once you include the plugin you're not preventing the default behaviour on the click event so it goes directly to the anchor, which completely removes any animation and most likely is moving the menu. Finally you have this in your code:

gsap.to("#section" + (index + 1), {
  duration: 1,
  scrollTo: { y: "#section" + (index + 1) }
});

Basically you're telling GSAP to scroll the element with the specific ID, you have to scroll the window object since that is the scroller element in your setup. This seems to work as you expect (albeit with some calculation errors it looks like, but you should be able to figure those out):

document.querySelectorAll(".scrollNav a").forEach((btn, index) => {
  btn.addEventListener("click", (e) => {
    e.preventDefault();
    gsap.to(window, {
      duration: 1,
      scrollTo: {
        y: "#section" + (index + 1),
        autoKill: true,
      }
    });
  });
});

Hopefully this helps. Let us know if you have more questions.

Happy Tweening!

  • Like 1
Link to comment
Share on other sites

Hey Rodrigo,

 

So this does indeed answer my question but I'm still left with one more problem now is that it's scroll past the sections.

 

Which you said there is some calculations errors that I'll have to figure out. 

 

Currently trying to figure out about how I calculate those and get it land on the section it was clicked on.

 

What should I be reading in the docs?

 

Updated code: 

See the Pen QWBPLzK by DilionsCode (@DilionsCode) on CodePen

 

Thank you,

Dilion Smith

Link to comment
Share on other sites

So here is my code for scrollTo functionality now:

 

  // Smooth scrolling on anchor links
  document.querySelectorAll(".scrollNav a").forEach((btn, index) => {
    btn.addEventListener("click", (e) => {
      e.preventDefault();
      var sectionNum = "#section" + (index + 1);
      var divHeight = $(sectionNum).height(); // Get Height of section inside #scrollArea
      var scrollHeight = $(sectionNum).offset().top - (divHeight); // create offset with the top
      console.log(sectionNum + ":" + scrollHeight);
      gsap.to(window, {
        duration: 2,
        scrollTo: {
          y: scrollHeight, // pass the final calculation
          ease:Power2.easeOut,
          autoKill: true,
        }
      });
    });
  });

 

Only issue that I'm having is that if the user goes down to section five but wants to return to a section above it; the calculation isn't working right.

 

Trying to combat this right now and figure out why that is. Can someone please tell me if my calculation is wrong? or how I'm inputting said calculation is the issue?

 

Thank you!

Link to comment
Share on other sites

Hi,

 

Indeed as mentioned the issue was in the calculations since on every click (even on the same anchor) you'll get different values.

 

This seems to work as expected:

if (!mobile.matches) {
  t = gsap.to(scrollArea, {
    //as user scrolls down on desktop the slides will scroll vertically
    y: scrollArea.clientHeight * -1,
    ease: "none",
    scrollTrigger: {
      trigger: ".scrollArea",
      pin: ".scrollSection",
      scrub: 1,
      start: "top 140px",
      end: "bottom bottom"
    }
  });
}

document.querySelectorAll(".scrollNav a").forEach((btn, index, btns) => {
  btn.addEventListener("click", (e) => {
    e.preventDefault();
    const start = t.scrollTrigger.start;
    const end = t.scrollTrigger.end;
    const partial = (end - start) / btns.length;
    gsap.to(window, {
      duration: 2,
      scrollTo: {
        y: start + partial * index,
        ease: Power2.easeOut,
        autoKill: true
      }
    });
  });
});

The explanation of the code is as follows. Each ScrollTrigger instance has a start and end point that gets updated on every refresh, that's why I stored the instance in a constant, in order to access that easily. Regarding the animation, super important to have it with ease: "none" because that guarantees that every section will use the same amount of scrolling (using any other easing function will change that). Finally get the amount of scroll for each section based on the number of sections const partial = (end - start) / (btns.length); 

 

Here is a live example:

See the Pen poZXLeE by GreenSock (@GreenSock) on CodePen

 

Hopefully this helps.

Happy Tweening!

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...