admin管理员组

文章数量:1317909

Do you know why scroll-behavior: smooth doesn't work with Lenis library of smooth -scrolling? When I ment the Lenis code below it works fine. When I add the Lenis code it doesn't scroll smoothly when I click the tag with id.

const lenis = new Lenis({
  duration: 2.5
})

function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}
requestAnimationFrame(raf)

lenis.on('scroll', ScrollTrigger.update)

gsap.ticker.add((time) => {
  lenis.raf(time * 1000)
})
html {
  scroll-behavior: smooth;
}
 <h2><a class="c-btn" href="#pages-main">scroll down</a></h2>
 
  <section id="pages-main"></section>

Do you know why scroll-behavior: smooth doesn't work with Lenis library of smooth -scrolling? When I ment the Lenis code below it works fine. When I add the Lenis code it doesn't scroll smoothly when I click the tag with id.

const lenis = new Lenis({
  duration: 2.5
})

function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}
requestAnimationFrame(raf)

lenis.on('scroll', ScrollTrigger.update)

gsap.ticker.add((time) => {
  lenis.raf(time * 1000)
})
html {
  scroll-behavior: smooth;
}
 <h2><a class="c-btn" href="#pages-main">scroll down</a></h2>
 
  <section id="pages-main"></section>

Do you know why scroll-behavior: smooth doesn't work with Lenis library of smooth -scrolling? When I ment the Lenis code below it works fine. When I add the Lenis code it doesn't scroll smoothly when I click the tag with id.

const lenis = new Lenis({
  duration: 2.5
})

function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}
requestAnimationFrame(raf)

lenis.on('scroll', ScrollTrigger.update)

gsap.ticker.add((time) => {
  lenis.raf(time * 1000)
})
html {
  scroll-behavior: smooth;
}
 <h2><a class="c-btn" href="#pages-main">scroll down</a></h2>
 
  <section id="pages-main"></section>

Share Improve this question asked Oct 30, 2023 at 9:51 blosiublosiu 531 silver badge7 bronze badges 0
Add a ment  | 

5 Answers 5

Reset to default 3

You need to use lenis-scroll's 'scrollTo' method to handle the smooth scroll and anchor link:

'use client' //If you're using NextJS
import { useLenis } from 'lenis/react';

const AnchorLink = () => {
  const lenis = useLenis();
 
  return (
  <span
  onClick={() => {
    lenis?.scrollTo("#pages-main");
  }}
    Click Me
  </span>)
}

You can also pass in an options object as a second parameter to scroll to. You can also refer to their documentation about this

import { LenisInstance, ScrollToParams, useLenis } from "@studio-freight/react-lenis";

// Using the useLenis hook to get a LenisInstance
  const lenisInstance: LenisInstance = useLenis();

  // Function for smooth scrolling
    const handleClick = (targetElement: string | number | HTMLElement)=>{

    if (targetElement) {
      const scrollToOptions: ScrollToParams = {
        // Customize scroll options if needed
        offset: 0,
        lerp: 0.1,
        duration: 1.5,
        easing: (rawValue: number) => rawValue, // Example easing function
        immediate: false,
        lock: false,
        force: false,
      };

      lenisInstance.scrollTo(targetElement, scrollToOptions);
    }
  }

I have used react-lenis for this but it should probably work with the normal lenis package as well.

Setting scroll-behavior: smooth on html will fix the scrolling on # links. BUT now the normal scrolling will get stuck. Apparently, lenis scroll works by taking control of the scroll on the html element and it doesn't keep it on smooth scroll to achieve the effect manually by javascript.

My solution for this was to write this fix along with the lenis initialization code -

// fix for id links
document.querySelectorAll('a[href^="#"]').forEach((el) => {
  el.addEventListener('click', (e) => {
    e.preventDefault()
    const id = el.getAttribute('href')?.slice(1)
    if (!id) return
    const target = document.getElementById(id)
    if (target) {
      target.scrollIntoView({ behavior: 'smooth' })
    }
  })
})

the only problem with this is that it won't update the url with #id if you try doing that with document.location.hash = "#id", it will again fallback to the default instant scroll.

The solution may be found in the Lenis documentation. You can use:

<a href="#anchor" onclick="lenis.scrollTo('#anchor')">scroll to anchor</a>

or use a function:

scrollTo(target, options)

target: goal to reach
number: value to scroll in pixels
string: CSS selector or keyword (top, left, start, bottom, right, end)
HTMLElement: DOM element

options.options
offset(number): equivalent to scroll-padding-top
lerp(number): animation lerp intensity
duration(number): animation duration (in seconds)
easing(function): animation easing
immediate(boolean): ignore duration, easing and lerp
lock(boolean): whether or not to prevent the user from scrolling until the target is reached
force(boolean): reach target even if instance is stopped
onComplete(function): called when the target is reached

My solution was to ment this rule from the lenis css.

/* .lenis.lenis-smooth {
    scroll-behavior: auto !important;
  } */

本文标签: javascriptSmooth scroll doesn39t work with Lenis when link with id clickedStack Overflow