You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Lenis平滑滚动在Firefox中元素下拉动画后无法滚动到底部

问题解决:Firefox中Lenis平滑滚动容器在元素动画后无法滚动到底部

补充说明:该功能在Chrome和Edge中正常运行。Windows平台最新版Safari(5.1.7)因不支持箭头函数(=>)且不再适配Windows 10更新,无法运行,但新版本Safari可能正常。本文问题针对Firefox!

问题描述

启用Lenis平滑滚动的.page容器内,有一个通过负margin-top隐藏的.filters-nav元素和触发按钮。点击按钮后,元素展开/收起,但容器无法滚动到底部,手动调整窗口大小后恢复正常。需要实现无需手动调整窗口,滚动自动恢复。

现有代码

Lenis初始化代码

const pageElements = document.querySelectorAll('.page');
pageElements.forEach((pageElement) => {
    const lenis = new Lenis({
        wrapper: pageElement,
        content: pageElement,
        duration: 1.2,
        easing: function(t){return (t === 1 ? 1 : 1 - Math.pow(2, -10 * t))},
        direction: 'vertical',
        gestureDirection: 'vertical',
        smooth: true,
        smoothWheel: true,
        smoothTouch: false,
        touchMultiplier: 2,
        autoResize: true,
    });
    function raf(time) {
        lenis.raf(time);
        requestAnimationFrame(raf);
    }
    requestAnimationFrame(raf);
});

按钮/元素动画代码

var $filtersnav = $('.filters-nav');
var filtersnavHeight = $filtersnav.height() + 30;
var clickCounter = 0;
$filtersnav.css('margin-top', -1 * filtersnavHeight);

$('.filters-bttn').click(function() {
    var $filtersnav = $('.filters-nav');
    var filtersnavHeight = $filtersnav.height() + 30;
    if (clickCounter % 2 === 0) {
        $filtersnav.css('margin-top', '0');
    } else {
        $filtersnav.css('margin-top', -1 * filtersnavHeight);
    }
    clickCounter++;
});

CSS代码

.page {
position: relative;
z-index: 5;
overflow-y: auto;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none;  /* Internet Explorer 10+ */
width: 100%;
height: 100vh;
pointer-events: auto;
background-color: #f7f7f7;
-webkit-transition: -webkit-transform 0.45s, opacity 0.45s;
transition: transform 0.45s, opacity 0.45s;
-webkit-transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1);
transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1);
}
.filters-bttn {
position:relative;
display:block;
height:50px;
z-index:2;
}
.filters-nav {
position:relative;
display:block;
-webkit-transition: all 0.65s ease;
transition: all 0.65s ease;
z-index:1;
}

解决方案

问题根源是Lenis未感知到容器内容高度变化,手动调窗口触发resize后才重新计算滚动范围。只需在元素动画完成后,手动调用Lenis的resize()方法即可。

修改后的代码

  1. 存储Lenis实例:将每个Lenis实例绑定到对应.page元素,方便后续调用
const pageElements = document.querySelectorAll('.page');

pageElements.forEach((pageElement) => {
    const lenis = new Lenis({
        wrapper: pageElement,
        content: pageElement,
        duration: 1.2,
        easing: function(t){return (t === 1 ? 1 : 1 - Math.pow(2, -10 * t))},
        direction: 'vertical',
        gestureDirection: 'vertical',
        smooth: true,
        smoothWheel: true,
        smoothTouch: false,
        touchMultiplier: 2,
        autoResize: true,
    });
    // 将实例绑定到元素上
    pageElement.lenisInstance = lenis;

    function raf(time) {
        lenis.raf(time);
        requestAnimationFrame(raf);
    }
    requestAnimationFrame(raf);
});
  1. 监听动画结束并触发resize:在.filters-nav过渡动画结束后,调用对应Lenis实例的resize()
var $filtersnav = $('.filters-nav');
var filtersnavHeight = $filtersnav.height() + 30;
var clickCounter = 0;
$filtersnav.css('margin-top', -1 * filtersnavHeight);

// 监听过渡结束事件
$filtersnav.on('transitionend', function() {
    // 找到当前元素所在的.page容器
    const pageElement = $(this).closest('.page')[0];
    // 调用Lenis实例的resize方法,重新计算滚动范围
    if (pageElement.lenisInstance) {
        pageElement.lenisInstance.resize();
    }
});

$('.filters-bttn').click(function() {
    var $filtersnav = $('.filters-nav');
    var filtersnavHeight = $filtersnav.height() + 30;
    if (clickCounter % 2 === 0) {
        $filtersnav.css('margin-top', '0');
    } else {
        $filtersnav.css('margin-top', -1 * filtersnavHeight);
    }
    clickCounter++;
});

原理说明

  • 绑定Lenis实例到.page元素,确保能精准找到当前容器对应的平滑滚动实例
  • 监听transitionend事件,保证元素动画完全结束后再更新尺寸,此时容器内容高度已稳定
  • 调用lenis.resize()手动触发Lenis重新计算容器滚动范围,替代手动调整窗口的效果,让滚动恢复正常

内容的提问来源于stack exchange,提问作者Igor Laszlo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:54:54