How to create anchor links without changing the site address when clicking on them?

Hi Webflowers

How to create anchor links without changing the site address when clicking on them?
I guess this is solved via attributes without adding an ID to the element


Here is my site Read-Only: LINK
(how to share your site Read-Only link)

I had to read your message about 3 times before I understood what you are asking. :laughing:

I think you are asking how to create a link that will scroll in-page to a specific section, without showing the #section fragment in the navigation bar.

Did I guess right?

The only way to do this is using javascript.

Let’s say you have a button, ID’d button1, and a section ID’d section1

You should be able to do something like this;

<script>
  document.getElementById('button1').addEventListener('click', function() {
    document.getElementById('section1').scrollIntoView({behavior: "smooth"});
  });
</script>
1 Like

Yes, you understood correctly and your code worked. Thank you very much, but I have one more problem:

  1. How to add a scroll delay to this script?
    I have a fullscreen menu which should close first and after that the scroll to the section should work

  2. Also I’m interested in the question How can I play around with the scroll animation and its duration?

And another question arose how to add multiple links to this code?
I added several links to the code and in the end only one about link works correctly for me.
When you click on Work and Contacts links, a tag is added to the site address.

<script>
  document.getElementById('link-about', 'link-work', 'link-contacts').addEventListener('click', function() {
    document.getElementById('section-about', 'section-work', 'section-contacts').scrollIntoView({behavior: "smooth"});
     });
</script>

that doesn’t work either

<script>
  document.getElementById('link-about').addEventListener('click', function() {
    document.getElementById('section-about').scrollIntoView({behavior: "smooth"});
     });
     
     document.getElementById('link-work').addEventListener('click', function() {
    document.getElementById('section-work').scrollIntoView({behavior: "smooth"});
     });
     
     document.getElementById('link-contacts').addEventListener('click', function() {
    document.getElementById('section-contacts').scrollIntoView({behavior: "smooth"});
     });
</script>

setTimeout is a delay, you could use it like below.
But I don’t thing that would close your menu. What you’re trying to do here is a bit nonstandard.

<script>
  document.getElementById('button1').addEventListener('click', function() {
    setTimeout(function() {
        document.getElementById('section1').scrollIntoView({behavior: "smooth"});
    }, 1000); // 1000 ms = 1 sec
  });
</script>

For multiple links, you need multiple copies of this, each with its own button id and section id.

Unfortunately, adding a delay only results in the menu simply closing but not scrolling to the section.

And cloning scripts with the rest of the links leads to the fact that when you click on them, the address field appears tag

I use on site Lenis scroll by T-Ricks.
I saw that in Lenis scroll you can integrate anchor links that will work with the help of attributes, but I don’t understand how it is possible to integrate them into a specific code from T-Ricks

It’s set to a 1 second delay which is a long time. Try playing with that- but I have no idea why you’re trying to delay or why that would improve your scrolling UX. Again, you’re doing some very nonstandard stuff here.

That’s not possible actually. Most likely, you still have your links defined as section links, so you’re getting both the link navigation and the script-based navigation conflicting.

If you need more help building this out, PM me and I can send you rates. Can’t do much else here without digging into your project and goals
directly.

1 Like

Fiddled around with the code a bit and got pretty much what i wanted :sunglasses:
Thank you very much for your attention and for solving my problem!

<script>
document.getElementById('link-about').addEventListener('click', function(event) {
  event.preventDefault();
  smoothScrollTo('section-about', 2000, 1000);
});

document.getElementById('link-work').addEventListener('click', function(event) {
  event.preventDefault();
  smoothScrollTo('section-work', 2000, 1000);
});

document.getElementById('link-contacts').addEventListener('click', function(event) {
  event.preventDefault();
  smoothScrollTo('section-contacts', 2000, 1000);
});

function smoothScrollTo(targetId, duration, delay) {
  const target = document.getElementById(targetId);
  const targetPosition = target.getBoundingClientRect().top + window.pageYOffset;
  const startPosition = window.pageYOffset;
  const distance = targetPosition - startPosition;
  const startTime = performance.now();

  function scrollAnimation(currentTime) {
    const elapsedTime = currentTime - startTime;
    if (elapsedTime < delay) {
      // Задержка: просто продолжаем ждать
      requestAnimationFrame(scrollAnimation);
      return;
    }

    const scrollProgress = ease(elapsedTime - delay, startPosition, distance, duration);
    window.scrollTo(0, scrollProgress);

    if (elapsedTime - delay < duration) {
      requestAnimationFrame(scrollAnimation);
    }
  }

  function ease(t, b, c, d) {
    t /= d / 2;
    if (t < 1) return c / 2 * t * t * t + b; // ease-in
    t -= 2;
    return c / 2 * (t * t * t + 2) + b; // ease-out
  }

  requestAnimationFrame(scrollAnimation);
}
</script>

Hello everyone,

a great solution. Unfortunately, I have the problem that the function should work with 35 buttons. But since only one ID per element is possible, I wanted to ask if anyone can help me. I think the best solution would be to rewrite the code so that an ID is not triggered by the click, but a class.

I don’t have any programming knowledge myself and ChatGPT couldn’t help me either. ChatGPT has suggested the following code (unfortunately this does not work):

<!DOCTYPE html>
<html lang="en">
<head>
  <!-- Head-Bereich -->
</head>
<body>

<div id="target">
  <!-- Inhalt des Ziel-Divs -->
</div>

<div class="fs-radio_field-1">
  <!-- Inhalt des klickbaren Divs -->
  Klick mich!
</div>

<script>
  // JavaScript-Code hier
  document.querySelector('.fs-radio_field-1').addEventListener('click', function() {
    document.getElementById('target').scrollIntoView({ behavior: "smooth" });
  });
</script>

</body>
</html>

In @iOstap 's approach above you can have as many buttons and as many scroll-to sections as you want. Just assign a unique ID to each button and each section, and repeat the click event setup;

document.getElementById('link-236').addEventListener('click', function(event) {
  event.preventDefault();
  smoothScrollTo('section-236', 2000, 1000);
});