Share Your Work

ben-duchy
Contributeur de premier rang

Highlight navigation on scroll

SOLVE

I've seen a nice navigation function on Codepen where the relevant link on the navigation highlights as you scroll further down the page. These links also work as anchor tags.

 

I've amended the CSS to allow for more links to be added which then creates a horizontal list, however I'm stuck on how to get the main navigation to automatically horizontally scroll as you scroll vertically. It's almost like I need a second anchor... Anyone have ideas?

0 Upvotes
1 Accepted solution
Teun
Solution
Key Advisor | Diamond Partner
Key Advisor | Diamond Partner

Highlight navigation on scroll

SOLVE

Hi @ben-duchy ,

 

Is this what you are looking for? If you scroll down a bit on the page on mobile you should see a sticky target menu.

 

We recently build this HubSpot site.

 

If this is what you need, I'll share the code.



Did my answer solve your issue? Help the community by marking it as the solution.

View solution in original post

4 Replies 4
Teun
Solution
Key Advisor | Diamond Partner
Key Advisor | Diamond Partner

Highlight navigation on scroll

SOLVE

Hi @ben-duchy ,

 

Is this what you are looking for? If you scroll down a bit on the page on mobile you should see a sticky target menu.

 

We recently build this HubSpot site.

 

If this is what you need, I'll share the code.



Did my answer solve your issue? Help the community by marking it as the solution.
ben-duchy
Contributeur de premier rang

Highlight navigation on scroll

SOLVE

Hi @Teun,

 

Thanks for your example, excellent work - it's exactly the type of navigation that I need to build 😀

 

On first glance of your code the JS looks very complicated. I'll do my best and let you know if it works. Do you think you could build a codepen version?

0 Upvotes
Teun
Key Advisor | Diamond Partner
Key Advisor | Diamond Partner

Highlight navigation on scroll

SOLVE

Hi @ben-duchy ,

 

I checked your codepen, and I suppose this is what you are looking for:

module.html:

 

<section class="c-target-menu js-target-menu-wrapper">
  <div class="c-target-menu__wrapper js-target-menu">
    <div class="o-container">
      <div class="c-target-menu__container">
        {% for item in module.items %}
          <a href="#{{item.target}}" class="c-target-menu__item">{{item.title}}</a>
        {% endfor %}
      </div>
    </div>
  </div>
</section>

 

 

Javascript&colon;

 

import scrollMonitor from 'scrollmonitor';

const wrappers = document.querySelectorAll('.js-target-menu-wrapper');
const targets = document.querySelectorAll('.js-target');

if (wrappers.length < 1) return;

[...wrappers].forEach(wrapper => {
  const menu = wrapper.querySelector('.js-target-menu');
  wrapper.style.height = menu.clientHeight + 'px'; // Set container to have the same height as menu
  const menuWatcher = scrollMonitor.create(menu, menu.clientHeight);

  menuWatcher.lock(); // Lock the current position of the element
  menuWatcher.stateChange(() => {
    if (menuWatcher.isAboveViewport) {
      document.body.classList.add('target-menu-active');
      menu.classList.add('active');
    } else {
      document.body.classList.remove('target-menu-active');
      menu.classList.remove('active');
    }
  });
});

if (targets.length < 1) return;

[...targets].forEach(target => {
  const targetWatcher = scrollMonitor.create(target);
  const link = document.querySelector(`a[href="#${target.id}"]`);
  const menu = link.parentNode;
  const linkPosition = link.getBoundingClientRect();

  targetWatcher.stateChange(() => {
    if (link) {
      if (targetWatcher.isInViewport) {
        link.classList.add('active');

        if (document.body.classList.contains('target-menu-active')) {
          menu.scrollTo({ top: linkPosition.top, left: linkPosition.left - 10, behavior: 'smooth' }); // Scroll element in view if it is outside viewport
        }
      } else {
        link.classList.remove('active');
      }
    }
  });
});

 

This part scrolls the menu horizontally if it is outside the viewport:

 

menu.scrollTo({ top: linkPosition.top, left: linkPosition.left - 10, behavior: 'smooth' });

 


I have multiple divs with an ID on the page that matches the link of each menu item. Those are called the 'targets'.



Did my answer solve your issue? Help the community by marking it as the solution.
0 Upvotes
Jaycee_Lewis
Community Manager
Community Manager

Highlight navigation on scroll

SOLVE

Hey, @ben-duchy Thanks for reaching out.

 

Are you able to provide an example of the code you've already written and where specifically y you are getting stuck. The Codepen link is helpful in understanding what your end goal is, but our community will need more info to help with your issue. @Teun@stefen, and @Stephanie-OG have you built out anything like what @ben-duchy is showing in their linked example? 

 

 

Thanks!  – Jaycee

linkedin

Jaycee Lewis

Developer Community Manager

Community | HubSpot

0 Upvotes