skip to Main Content

I’m trying to implement a smooth scrolling effect using javascript for anchors in a main menu. The links in the menu look like <a href="/#target">.

This code works fine when clicking on the links on the same page as the anchors:

    Object.entries(document.querySelectorAll('[href*="#"]'))
    .forEach(([ index, node ]) => {
        node.addEventListener('click', (event) => {
                const target = event.currentTarget.getAttribute('href').replace('/','');
            event.preventDefault();

            window.scrollTo({
                top: document.querySelector(target).getBoundingClientRect().top - 50,
                behavior: 'smooth'
            });
        });
    });

but not when clicking from another page. From the other page, it jumps directly to the anchor for one of the links, and for another further down the page, it’s a few 100 pixels too high.

I can’t use scroll-behavior: smooth either because the page also has other javascript carousels on it, and there seems to be a bug relating to Chromium and requestAnimationFrame.

Edit: updated code based on Brad’s suggestion.

const scrollToTarget = (target) => {
    window.scrollTo({
        top: document.querySelector(target).getBoundingClientRect().top - 50,
        behavior: 'smooth'
    });
}

const scrollTo = (target) => {
    event.preventDefault();
    const home = document.querySelector('.page-home');
    if (home) {
        scrollToTarget(target)
    } else {
        window.location.href = '/';
        window.addEventListener('DOMContentLoaded', function () {
            setTimeout(scrollToTarget(target), 2000);
        });
    }
}

const link1 = document.querySelector('.link-1');
const link2 = document.querySelector('.link-2');

link1.addEventListener('click', (event) => { scrollTo('#one'); });
link2.addEventListener('click', (event) => { scrollTo('#two'); });

2

Answers


  1. This isn’t possible directly, as there isn’t really a solid context between Page A and Page B.

    At best, you can remove all the actual anchors on the "receiving" Page B and then have your JavaScript scroll to the appropriate place once loaded. This is a really bad practice however, in terms of usability.

    Login or Signup to reply.
  2. Create anchor tags with unique id attributes on the destination page. For example, if you want to scroll to a section with the id "section1" on the destination page, your anchor tag should look like this:

    <a id="section1"></a>
    
    // Smooth scroll to anchor links
    function smoothScrollToAnchor() {
      const links = document.querySelectorAll('a[href^="#"]');
      links.forEach(link => {
        link.addEventListener('click', function(e) {
          e.preventDefault();
          const href = this.getAttribute('href');
          const target = document.querySelector(href);
          if (target) {
            const offsetTop = target.offsetTop;
            const scrollOptions = {
              top: offsetTop,
              behavior: 'smooth'
            };
            window.scrollTo(scrollOptions);
          }
        });
      });
    }
    Create anchor tags with unique id attributes on the destination page. For example, if you want to scroll to a section with the id "section1" on the destination page, your anchor tag should look like this:
    
    <a id="section1"></a>
    On the source page, create links or buttons that trigger the smooth scrolling to the anchors on the destination page. For example:
    
    <a href="destination-page.html#section1">Scroll to Section 1</a>
    Add the following JavaScript code to your source page. This code will handle the smooth scrolling behavior:
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search