GSAP的ScrollSmoother插件通过不断更新ScrollSmoother的Content元素translateY值来替换浏览器自身的页面滚动来实现平滑滚动,但这会导致内容区域里的元素使用position:fixed;样式失效。常规的解决方法是把使用了position:fixed;样式的元素放置在ScrollSmoother的wrapper元素外观,但如果有非要把position:fixed;样式元素放置在ScrollSmoother的Content元素内的需求,可以考虑通过使用ScrollSmoother的回调函数onUpdate来不断更新固定元素的值来替代实现,这种方法有个瑕疵,就是在移动端滚动页面时会出现抖动,目前还没有解决。
参考代码:
HTML代码:
<!--ScrollSmoother元素--> <div id="main-wrapper"> <div id="main-content"> </div> </div> <!--需要fixed的元素--> <div class="fixed-popup"> <div class="content"> 内容 </div> </div>
CSS代码:
/*固定在浏览器窗口底部*/ .fixed-popup { position: absolute; z-index: 9; left:0; bottom:0; width: 100%; padding:60px 0; box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1); background-color: #fff; overflow: hidden; visibility: hidden; opacity: 0; will-change: transform; }
JS代码:
gsap.registerPlugin(ScrollSmoother); const smoother = ScrollSmoother.create({ smooth: 1, effects: true, normalizeScroll: false, wrapper:'#main-wrapper', content:'#main-content', onUpdate: (self) => { const currentScrollY = self.scrollTop(); //ScrollSmoother滚动的距离 const fixedPopup = document.querySelector('.fixed-popup'); if(fixedPopup){ const viewportHeight = window.innerHeight; //窗口高度 const elementHeight = fixedPopup.offsetHeight; //要固定的元素高度 gsap.set(fixedPopup, { y: currentScrollY + viewportHeight - elementHeight, //滚动的距离+窗口高度-固定的元素高度=元素固定在浏览器窗口的数值 duration:1 }); } } });
PS:如果只用在PC电脑端,实际效果和position:fixed;几乎没有差异。