locomotive-scroll icon indicating copy to clipboard operation
locomotive-scroll copied to clipboard

anchor link does not work with scroll locomotive

Open GeorgeStudio96 opened this issue 4 years ago • 27 comments

Hi, everybody, can you please tell me how I can create an anchor link in Header to a certain block that has an ID that is in the data-scroll-container ? I've tried to put my menu FOR the limits of the data-scroll-container, I've tried to put it into this shell and none of the options have helped me :( I'd appreciate it if you could help me write a few lines of code to make it work. Thank you . I have tried for a long time to consider this example, but I cannot understand how it all works. They are fine, when you click on 02.Scroll-direction and the page flips smoothly to the desired block. Help me understand what to do https://locomotivemtl.github.io/locomotive-scroll/

If necessary, I can recreate the example on codepen, but please see my example first to understand what I'm talking about. https://george-studio.webflow.io/ If you click on Home you will be redirected to the right place, but everything breaks down. The script breaks, you can't go back, when you refresh a page, I am immediately redirected to this link. I'm sure I'm doing something wrong, help me understand what it is.

GeorgeStudio96 avatar Oct 16 '20 19:10 GeorgeStudio96

Any luck finding the fix?

shohinav avatar Oct 20 '20 02:10 shohinav

Any luck finding the fix?

No..:(

GeorgeStudio96 avatar Oct 20 '20 07:10 GeorgeStudio96

I found a solution for this. You will need to use JS for this and remove the link from the anchor tag just leaving it empty with # only. So something like this:

const slider= document.querySelector('#slider-container');

$('.w-nav-link:first-child').on('click', function() {
    scroll.scrollTo(slider)
});

Not sure if it's the right way, but as long as it works. Hopefully this helps

shohinav avatar Oct 20 '20 07:10 shohinav

I may be doing something wrong but there is no result... I used your code. Where "#slider-container is the block ID" to which should be scrolled. and ".home" is the class of the first link I click on.

GeorgeStudio96 avatar Oct 20 '20 15:10 GeorgeStudio96

for now you can try moving the "w-container" outside of the data-scroll-container so it isn't affected by scrolling.

ronca85 avatar Oct 24 '20 01:10 ronca85

for now you can try moving the "w-container" outside of the data-scroll-container so it isn't affected by scrolling.

No, this option does not work. You can see that I left just a normal link on the site outside the data-scroll container. and nowhere is there a codepen with a locomotive + anchor link? this is such a big problem... although the task is supposedly simple

GeorgeStudio96 avatar Oct 24 '20 14:10 GeorgeStudio96

can you show me a demonstration on codepen?

GeorgeStudio96 avatar Oct 24 '20 19:10 GeorgeStudio96

@GeorgeStudio96 put href="#slider-container" on one of your anchors. currently it says href="#"

ronca85 avatar Oct 27 '20 02:10 ronca85

@ GeorgeStudio96 поместил href = "# slider-container" в одну из ваших якорей. в настоящее время он говорит: href = "#"

https://codepen.io/GeorgeDesign2020/pen/bGeWNOE I created a demonstration where you can see 2 methods yours and @shohinav. I put a #black in link 2 and if you click it will scroll to the desired section, but scrolling the locomotive stops working correctly, look at the demonstration. option @shohinav, for link 3 I left # empty and finished the jquery script, it is written at the very end of JS. In this example there is 0 reaction at all when you click on link 3. What to do? why is it so difficult when it's elementary things? why didn't the locomotive scroll take care to recreate a piece of code for these basic and elementary things? I have a long website and I want the user to quickly switch to the sections he needs.

GeorgeStudio96 avatar Oct 27 '20 09:10 GeorgeStudio96

another thing, I have an extra gsap code there which I did not recreate in this example, but my site uses a lot of GSAP animation + three js.

GeorgeStudio96 avatar Oct 27 '20 09:10 GeorgeStudio96

@GeorgeStudio96 I found the issue for link 3(the solution I suggested you), in the JS file your declared the Locomotive Scroll as locoScroll, but for the scrollTo you put scroll instead of putting locoScroll, so it should be as:

const slider= document.querySelector('#about');

$('.anchor__link:nth-child(3)').on('click', function() {
    locoScroll.scrollTo(slider)
});

this worked for me

shohinav avatar Oct 27 '20 09:10 shohinav

@GeorgeStudio96 I found the issue for link 3(the solution I suggested you), in the JS file your declared the Locomotive Scroll as locoScroll, but for the scrollTo you put scroll instead of putting locoScroll, so it should be as:

const slider= document.querySelector('#about');

$('.anchor__link:nth-child(3)').on('click', function() {
    locoScroll.scrollTo(slider)
});

this worked for me

YES! thank you so much, now it works. Yes, it turns out to be my mistake, I did not understand what I was talking about. Now everything works as it should! Now I have the same question as you. is it the right way to do it?)) how can we know if it's the right way to do it? because we are plugging jquery in.

GeorgeStudio96 avatar Oct 27 '20 09:10 GeorgeStudio96

Hello.

I would like contribute with this case.

I did my anchor link works just using the attribute data-scroll-to, like this:

<a href="#end" class="go-to-end" data-scroll-to><i class="fas fa-chevron-down"></i></a>

I got it of the inspect tool of page that @GeorgeStudio96 post here (https://locomotivemtl.github.io/locomotive-scroll/)

aaamenezes avatar Dec 08 '20 13:12 aaamenezes

Hello.

I would like contribute with this case.

I did my anchor link works just using the attribute data-scroll-to, like this:

<a href="#end" class="go-to-end" data-scroll-to><i class="fas fa-chevron-down"></i></a>

I got it of the inspect tool of page that @GeorgeStudio96 post here (https://locomotivemtl.github.io/locomotive-scroll/)

What? I don't understand where your link goes. You created data-scroll-to, gave a class to your tag, then logically you have to put an attribute to the element we want to get to, right? for example to the section with the attribute or something. What is it ? oO

GeorgeStudio96 avatar Dec 16 '20 13:12 GeorgeStudio96

In really, you just need put a attribute in the anchor link where the user clicks, and not in the target element.

The anchor link in my example points to element with <div id="end"> ... </div>.

The only diference between anchor link using LocomotiveScroll or not, is that with Locomotive you need put the attribute data-scroll-to inside your anchor link. That's it.

aaamenezes avatar Dec 19 '20 23:12 aaamenezes

In really, you just need put a attribute in the anchor link where the user clicks, and not in the target element.

The anchor link in my example points to element with <div id="end"> ... </div>.

The only diference between anchor link using LocomotiveScroll or not, is that with Locomotive you need put the attribute data-scroll-to inside your anchor link. That's it.

I tested your, method, it works, but after I move to my section, I can no longer scroll to the top. There is probably some conflict between the Webflow and locomotive scroll scripts. Too bad...

GeorgeStudio96 avatar Dec 23 '20 16:12 GeorgeStudio96

It is certainly a conflict with LocomotiveScroll. Here at my company, none of us like to use this library, and we use it only because the customer asked.

The behavior you described to me is as if the data-scroll-to attribute has not yet been set. That's how the anchor link used to behave before for me.

In my case, just put this attribute and scrolling is no longer a problem, even if it runs smoothly.

I apologize for any problems with my text. I'm Brazilian and I'm writing with the help of Google Translate.

aaamenezes avatar Dec 23 '20 21:12 aaamenezes

Hello friends. I was grappling with this, the solution for me was

<a href="#section6" data-scroll-to>Go to section 6</a>

but this will only work inside this container

<div data-scroll-container>

If this data-scroll-to attribute is outside this link, it explodes. JS solution also did not work for me unfortunately. Was surprised to not see this "data-scroll-to" on the locomotive js docs. Unless I missed it....

DoubleMarv avatar Mar 12 '21 15:03 DoubleMarv

this feels a little weird, if I add data-scroll-to, it works on desktop, but not on my smartphone (guess because there's still the e.preventDefault when you click on the anchor, but the smooth scrolling is not enabled), also, if I add the anchor in the url (like localhost:1234#contact) it's scrolling there, but then I cannot scroll up again :(

edit: solution for me was to use href="#id" and data-scroll-to for desktop and a custom js function for mobile, where if the html doesn't have the active smooth class I add scrollIntoView when clicking the anchor links

jankohlbach avatar Apr 12 '21 19:04 jankohlbach

Here's a little script for you guys.

	/* Locomotive Anchor Scroll */

	const anchorLinks = document.querySelectorAll('a[href^=\\#]:not([href$=\\#])');

	anchorLinks.forEach((anchorLink) => {
		let hashval = anchorLink.getAttribute('href');
		let target = document.querySelector(hashval);

		anchorLink.addEventListener('click', (e) => {
			e.preventDefault();
			e.stopPropagation();

			scrollLocomotive.scrollTo(target);
		});
	});

It triggers on all anchor links that have actual target ("/#div_id") and ignore the empty ones ("/#").

mykt0ngc0 avatar Mar 30 '22 02:03 mykt0ngc0

Set Active Class into anchor Link.

const anchorLinks = document.querySelectorAll(
    'a[href^=\\#]:not([href$=\\#])'
  );

  anchorLinks.forEach((anchorLink) => {
    let hashval = anchorLink.getAttribute('href');
    let target = document.querySelector(hashval);

    anchorLink.addEventListener('click', (e) => {
      e.preventDefault();
      e.stopPropagation();

      anchorLinks.forEach((anchorLink) => {
        anchorLink.classList.remove('active');
      });

      e.target.classList.add('active');

      scroll.scrollTo(target);
    });
  });

mhasan320 avatar Apr 21 '22 19:04 mhasan320

I spent ages trying to get this working but eventually reached a solution with the code from @mykt0ngc0 above.

For my html, I needed the fixed-nav outside of the data-scroll container, and needed the data-scroll-to attribute on each of the a tags:

<nav class="fixed-nav">
    <ul>
      <li><a href="#location1"
           class="location location--1"
           data-scroll-to>location one</a></li>
      <li><a href="#location2"
           class="location location--2"
           data-scroll-to>location2</a></li>
      <li><a href="#location3"
           class="location location--3"
           data-scroll-to>
          location3</a></li>
      <li><a href="#location4"
           class="location location--4"
           data-scroll-to>location4</a></li>
      <li><a href="#location5"
           class="location location--5"
           data-scroll-to>location5</a></li>
    </ul>
  </nav>

My js for the nav then looked like this:

const anchorLinks = document.querySelectorAll('.fixed-nav .location');

anchorLinks.forEach((anchorLink) => {
  let hashval = anchorLink.getAttribute('href');
  let target = document.querySelector(hashval);

  anchorLink.addEventListener('click', (e) => {
    e.preventDefault();
    e.stopPropagation();

    locomotiveScroll.scrollTo(target);
  });
});

This combo seems to work.

Additionally, after the DOM first paints, I was getting another bug with locomotive, so I found this piece of code and slightly reworked it to resolve it, so my full locomotive file looks like this:

import LocomotiveScroll from 'locomotive-scroll';

const locomotiveScroll = new LocomotiveScroll({
  el: document.querySelector('[data-scroll-container]'),
  smooth: true,
  getSpeed: true,
  getDirection: true,
  inertia: 0.75,
});

document.addEventListener('DOMContentLoaded', function () {
  function ScrollUpdateDelay() {
    setTimeout(function () {
      locomotiveScroll.update();
    }, 1000);
  }

  ScrollUpdateDelay();
});

const anchorLinks = document.querySelectorAll('.fixed-nav .location');

anchorLinks.forEach((anchorLink) => {
  let hashval = anchorLink.getAttribute('href');
  let target = document.querySelector(hashval);

  anchorLink.addEventListener('click', (e) => {
    e.preventDefault();
    e.stopPropagation();

    locomotiveScroll.scrollTo(target);
  });
});

luxjoshyua avatar Sep 30 '22 05:09 luxjoshyua

This is beautiful and exactly what I needed, thank you @mykt0ngc0 @mhasan320 and @luxjoshyua!

To reiterate the [data-scroll-to] works perfectly fine inside a [data-scroll-container] but all other instances should reference the code and DOM structure above.

Any ideas how to introduce a little offset for the scrollTo function? Edit, actually appears to be as easy as passing the following offset into that scrollTo function: locomotiveScroll.scrollTo(target, , {offset: -100})

artshostak avatar Nov 29 '22 18:11 artshostak

Here is the solution if you want to use Locomotive Scroll with Gsap Scroll trigger and also anchor links to work correct.

Be sure you use data-scroll, data-scroll-section and data-scroll-to in your Html.

HTML

<section data-scroll-section id="first">
    <h1 data-scroll>Hey</h1>
    <p data-scroll>👋</p>
</section>

<section data-scroll-section id="second">
    <h2 data-scroll data-scroll-speed="1">What's up?</h2>
    <p data-scroll data-scroll-speed="2">😬</p>
</section>

JAVASCRIPT

const locoScroll = new LocomotiveScroll({ el: document.querySelector('[data-scroll-container]'), smooth: true, });

/* Add this script if you want to Loco Scroll to work with Gsap scrollTrigger */

locoScroll.on("scroll", ScrollTrigger.update);

ScrollTrigger.scrollerProxy("[data-scroll-container]", { scrollTop(value) { return arguments.length ? locoScroll.scrollTo(value, {duration: 0, disableLerp: true}) : locoScroll.scroll.instance.scroll.y; }, getBoundingClientRect() { return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight}; }, pinType: document.querySelector("[data-scroll-container]").style.transform ? "transform" : "fixed" }); ScrollTrigger.addEventListener("refresh", () => locoScroll.update()); ScrollTrigger.defaults({ scroller: "[data-scroll-container]" });

/* Add This script For Anchor to work in loco sroll */ const anchorLinks = document.querySelectorAll('a[href^=\#]:not([href$=\#])');

anchorLinks.forEach((anchorLink) => {
	let hashval = anchorLink.getAttribute('href');
	let target = document.querySelector(hashval);

	anchorLink.addEventListener('click', (e) => {
		e.preventDefault();
		e.stopPropagation();

		locoScroll.scrollTo(target);
	});
});

r4sk4t0v avatar Apr 18 '23 12:04 r4sk4t0v

@GeorgeStudio96 I found the issue for link 3(the solution I suggested you), in the JS file your declared the Locomotive Scroll as locoScroll, but for the scrollTo you put scroll instead of putting locoScroll, so it should be as:

const slider= document.querySelector('#about');

$('.anchor__link:nth-child(3)').on('click', function() {
    locoScroll.scrollTo(slider)
});

this worked for me

Thank you so much dear friend. Tried many different JS methods and such to solve this issue but was not helpful. This worked

ShadowSlayer03 avatar Mar 05 '24 18:03 ShadowSlayer03