lenis滑动插件的笔记

发布于:2025-05-13 ⋅ 阅读:(17) ⋅ 点赞:(0)

官网

lenis - npm

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

通过 Lenis 自带的 scroll 和 limit 属性直接判断:

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 的含义和使用场景,可以更高效地开发与滚动相关的交互功能,同时避免手动计算滚动边界的繁琐操作。


网站公告

今日签到

点亮在社区的每一天
去签到