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;几乎没有差异。