GSAP ScrollSmoother插件内容区域不支持position:fixed样式属性的替代方案

Web前端开发 / 20 次阅读

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