lenis滑动插件的笔记

官网

lenis - npm

方法一:基础判断(推荐)

通过 Lenis 自带的 scrolllimit 属性直接判断:

复制代码
const lenis = new Lenis()

// 滚动事件监听
lenis.on('scroll', ({ scroll, limit }) => {
  const distanceToBottom = limit - scroll
  const threshold = 100 // 距离底部100px触发
  
  if (distanceToBottom < threshold) {
    console.log('接近底部')
    // 执行加载更多等操作
  }
})

方法二:动态内容适配

当页面内容动态增加时,需要 ​​重置 Lenis 的尺寸计算​​:

复制代码
// 加载新内容后调用
function loadMoreData() {
  fetch('/api/data').then(() => {
    // 1. 插入新内容到DOM
    // 2. 通知Lenis重新计算
    lenis.resize() // 关键方法
  })
}

// 在滚动监听中
lenis.on('scroll', ({ scroll, limit }) => {
  if (limit - scroll < 100) {
    loadMoreData()
  }
})

方法三:精确计算模式

针对复杂布局(如存在浮动元素、position: sticky 等):

复制代码
function isBottom() {
  // 获取 Lenis 的滚动容器
  const wrapper = lenis.wrapperElement || document.documentElement
  
  // 精确计算可滚动范围
  const actualLimit = wrapper.scrollHeight - wrapper.clientHeight
  const currentScroll = lenis.scroll
  
  return currentScroll >= actualLimit - 1 // 消除计算误差
}

// 使用示例
if (isBottom()) {
  console.log('精确到达底部')
}

⚠️ 注意事项

  1. ​性能优化​

    在滚动事件中使用防抖(建议直接使用 Lenis 的 RAF 机制):

    复制代码
    function checkBottom() {
      if (lenis.isScrolling) return // 滚动中不检测
      // 检测逻辑
    }

    移动端适配​

    兼容触摸屏惯性滚动

    复制代码
    lenis.on('scroll', ({ scroll, limit, velocity }) => {
      if (velocity > 0.1 && limit - scroll < 500) {
        // 快速滑动时提前加载
      }
    })

    方向判断​

    只在下滑时检测:

    复制代码
    let lastScroll = 0
    lenis.on('scroll', ({ scroll }) => {
      const isScrollingDown = scroll > lastScroll
      lastScroll = scroll
      
      if (isScrollingDown && isBottom()) {
        // 处理底部逻辑
      }
    })

    完整示例(React 版)

    复制代码
    import { useEffect, useRef } from 'react'
    import Lenis from '@studio-freight/lenis'
    
    function App() {
      const lenisRef = useRef()
    
      useEffect(() => {
        const lenis = new Lenis()
        lenisRef.current = lenis
    
        const checkBottom = () => {
          const { scroll, limit } = lenis
          if (limit - scroll < 100) {
            console.log('触发加载')
            // 此处执行加载逻辑
          }
        }
    
        const raf = (time) => {
          lenis.raf(time)
          checkBottom()
          requestAnimationFrame(raf)
        }
        requestAnimationFrame(raf)
    
        return () => lenis.destroy()
      }, [])
    
      return (
        <div>{/* 页面内容 */}</div>
      )
    }

    回调函数中的实参limit

关键特性
动态计算

Lenis 的阻尼效果会使实际滚动值略微超过 limit,但最终会回弹到 limit 值:

3. 边界缓冲
  • 当页面高度变化时(例如加载更多内容),需手动调用 lenis.resize() 更新:

    复制代码
    // 加载新内容后
    document.body.appendChild(newContent)
    lenis.resize() // 重新计算 limit
    方向差异
  • ​垂直滚动​ : limit = scrollHeight - innerHeight

  • ​水平滚动​ : limit = scrollWidth - innerWidth(需配置 Lenis 为横向滚动)

    // 启用阻尼效果后
    console.log(lenis.isScrolling) // 当滚动超过 limit 时为 true

应用场景

1. 无限滚动加载
复制代码
lenis.on('scroll', ({ scroll, limit }) => {
  if (limit - scroll < 100) {
    loadMoreContent()
  }
})
返回顶部按钮
复制代码
const showButton = scroll > 0.3 * limit

进度指示器

复制代码
const progress = Math.min(scroll / limit, 1)

对比原生属性

场景 原生方法 Lenis 方法 优势
静态页面 window.scrollY + scrollHeight 计算 直接使用 limit 无需手动计算
动态加载内容 需监听 DOM 变化并重新计算 调用 resize() 即可 自动处理复合滚动容器
有 transform 的容器 可能计算错误 结果准确 正确处理 CSS transform 和复杂布局
横向滚动 需单独处理 scrollWidth 统一使用 limit 代码逻辑一致

六、特殊案例处理

存在 position: sticky 元素
复制代码
// 手动补偿 sticky 元素高度
const stickyElement = document.querySelector('.sticky')
const adjustedLimit = limit - stickyElement.offsetHeight
多滚动容器

如果 Lenis 被配置为控制某个子容器:

复制代码
const lenis = new Lenis({
  wrapper: document.getElementById('custom-scroll-container'),
  content: document.getElementById('custom-content')
})

// 此时 limit 对应的是容器内部的滚动极限

通过理解 limit 的含义和使用场景,可以更高效地开发与滚动相关的交互功能,同时避免手动计算滚动边界的繁琐操作。

相关推荐
weifont23 分钟前
React中的useSyncExternalStore使用
前端·javascript·react.js
初遇你时动了情28 分钟前
js fetch流式请求 AI动态生成文本,实现逐字生成渲染效果
前端·javascript·react.js
几何心凉1 小时前
如何使用 React Hooks 替代类组件的生命周期方法?
前端·javascript·react.js
小堃学编程1 小时前
前端学习(1)—— 使用HTML编写一个简单的个人简历展示页面
前端·javascript·html
运维@小兵2 小时前
vue访问后端接口,实现用户注册
前端·javascript·vue.js
雨汨3 小时前
web:InfiniteScroll 无限滚动
前端·javascript·vue.js
小盐巴小严3 小时前
正则表达式
javascript·正则表达式
天天打码4 小时前
Rspack:字节跳动自研 Web 构建工具-基于 Rust打造高性能前端工具链
开发语言·前端·javascript·rust·开源
AA-代码批发V哥4 小时前
正则表达式: 从基础到进阶的语法指南
java·开发语言·javascript·python·正则表达式
字节高级特工4 小时前
【C++】”如虎添翼“:模板初阶
java·c语言·前端·javascript·c++·学习·算法