Barba JS与Lenis Scroll滚动冲突问题求助
解决方案
1. 调整Barba beforeLeave阶段:等待Lenis滚动到顶部再执行过渡
直接停止Lenis会打断Barba的同步过渡流程,导致硬刷新。正确做法是先让Lenis平滑滚动到页面顶部,等滚动完成后再执行页面淡出动画,确保离开时页面处于顶部位置。
修改beforeLeave钩子:
beforeLeave: function(data) { let end = data.next.html.indexOf(' data-wf-site="'); let start = data.next.html.indexOf('data-wf-page="'); let string = data.next.html.slice(start, end); let arr = string.split('"'); pageID = arr[1]; const done = this.async(); // 先让Lenis平滑滚动到顶部,完成后再执行淡出 scrollInstance.lenis.scrollTo(0, { onComplete: () => { gsap.to(data.current.container, { opacity: 0, duration: 0.5, onComplete: done, }); } }); },
2. 在Barba过渡周期中正确管理Lenis状态
在页面进入前暂停Lenis,确保window.scrollTo生效;进入完成后恢复Lenis的滚动控制。
修改beforeEnter钩子:
beforeEnter: function(data) { $('html').attr('data-wf-page', pageID); window.Webflow && window.Webflow.destroy(); window.Webflow && window.Webflow.ready(); window.Webflow && window.Webflow.require('ix2').init(); window.Webflow && window.Webflow.require('lottie').lottie; if (introOverlay) { introOverlay.style.display = 'none'; } // 暂停Lenis,确保原生scrollTo生效 scrollInstance.lenis.stop(); // 强制滚动到顶部 window.scrollTo(0, 0); $("[js-line-animation-delayed]").each(function() { $(this).removeAttr("js-line-animation-delayed"); $(this).attr("js-line-animation", true); }); },
修改afterEnter钩子:
afterEnter: function(data) { setTimeout(() => { $("[js-line-animation]").each(function(index) { gsap.set($(this), { autoAlpha: 1 }); let textEl = $(this); let textContent = $(this).text(); let tl; function splitText() { new SplitType(textEl, { types: "lines", tagName: "span" }); textEl.find(".line").each(function(index) { let lineContent = $(this).html(); $(this).html(""); $(this).append(`<span class="line-inner" style="display: block;">${lineContent}</span>`); }); tl = gsap.timeline({ scrollTrigger: { trigger: textEl, start: "top bottom", end: "bottom bottom", toggleActions: "none play none reset" } }); tl.fromTo(textEl.find(".line-inner"), { yPercent: 100 }, { yPercent: 0, duration: 0.6, stagger: { amount: 0.4, ease: "power1.out" } }); } splitText(); let windowWidth = window.innerWidth; window.addEventListener("resize", function() { if (windowWidth !== window.innerWidth) { windowWidth = window.innerWidth; tl.kill(); textEl.text(textContent); splitText(); } }); }); barbaHeroHome(); // 页面动画完成后,重新启动Lenis平滑滚动 scrollInstance.lenis.start(); }, 100); },
3. 补全Scroll类的stop/start方法
确保Scroll类的方法正确绑定Lenis实例:
const Scroll = { // ... 原有代码 ... stop() { this.lenis.stop(); }, start() { this.lenis.start(); // 重新启动raf循环 this.render(); }, // ... 原有代码 ... };
关键原理
- 避免直接在beforeLeave阶段停止Lenis,通过Lenis自带的
scrollTo方法平滑回到顶部,既保留平滑体验,又保证离开位置正确。 - 在beforeEnter阶段暂停Lenis,让原生
window.scrollTo不受Lenis拦截,确保新页面加载后处于顶部。 - 页面完全进入并完成动画后,重新启动Lenis,恢复平滑滚动功能。
内容的提问来源于stack exchange,提问作者van
相关产品推荐
相关产品推荐

