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

ScrollMagic动画与滚动锁定功能异常问题求助

滚动锁定/解锁功能失效问题排查与修复

问题背景

开发Web项目时,使用ScrollMagic实现滚动触发动画,TimelineMax制作公司名称打字动画,需求是动画执行时锁定屏幕,用户滚动操作后解锁屏幕。目前动画触发正常,但滚动锁定与解锁功能无法正常工作,代码如下:

$(document).ready(function () {
    // Initialize the ScrollMagic Controller
    var controller = new ScrollMagic.Controller();

    // Create your first scene (ourScene)
    var ourScene = new ScrollMagic.Scene({
        triggerElement: '#project03'
    })
        .setClassToggle('#project03', 'fade-in');

    // Add the "typing" animation for the company name
    var textAnimation = new TimelineMax();
    var letters = document.querySelectorAll('#company-name span');
    letters.forEach(function (letter, index) {
        textAnimation.to(letter, 0.5, { opacity: 1, delay: index * 0.2 });
    });

    var companyNameScene = new ScrollMagic.Scene({
        triggerElement: '#company-name',
        triggerHook: 1,
        reverse: false
    })
        .setTween(textAnimation)
        .setClassToggle('#company-name', 'visible')
        .addTo(controller)
        .on("start", function () {
            $("body").css("overflow", "hidden");
        });

    var scrollFunction = function () {
        $("body").css("overflow", "auto");
        $(window).off("scroll", scrollFunction);
    };

    $(window).on("scroll", scrollFunction);

    ourScene.addTo(controller);
});

问题原因

  1. scroll事件绑定时机错误:页面加载完成后立即绑定了scroll事件,此时动画尚未触发,用户只要滚动页面就会直接解锁,完全没等到动画执行阶段。
  2. 滚动锁定不彻底:仅设置body的overflow:hidden在部分浏览器中无效,且未处理锁定时的页面滚动位置,容易出现页面跳动问题。
  3. 事件逻辑冲突:原代码中scroll事件只执行一次就解绑,但没有考虑动画执行过程中的交互逻辑,导致锁定状态无法维持。

解决方案

  1. 延迟绑定scroll事件:仅在动画开始触发后,再绑定scroll解锁事件,确保只有动画执行时的滚动操作才会触发解锁。
  2. 完善滚动锁定样式:同时锁定html和body,并记录当前滚动位置,通过position:fixed固定页面,避免跳动;解锁时恢复原有滚动位置和样式。
  3. 增加动画完成自动解锁:利用TimelineMax的回调,在打字动画结束后自动解锁滚动,提升用户体验。

修复后的完整代码

$(document).ready(function () {
    // Initialize the ScrollMagic Controller
    var controller = new ScrollMagic.Controller();
    let scrollPosition = 0;

    // Create your first scene (ourScene)
    var ourScene = new ScrollMagic.Scene({
        triggerElement: '#project03'
    })
        .setClassToggle('#project03', 'fade-in')
        .addTo(controller);

    // Add the "typing" animation for the company name
    var textAnimation = new TimelineMax();
    var letters = document.querySelectorAll('#company-name span');
    letters.forEach(function (letter, index) {
        textAnimation.to(letter, 0.5, { opacity: 1, delay: index * 0.2 });
    });

    // 滚动锁定函数
    const lockScroll = () => {
        scrollPosition = window.scrollY;
        $('html, body').css({
            'overflow': 'hidden',
            'position': 'fixed',
            'top': `-${scrollPosition}px`,
            'width': '100%'
        });
    };

    // 滚动解锁函数
    const unlockScroll = () => {
        $('html, body').css({
            'overflow': 'auto',
            'position': 'static',
            'top': 'auto'
        });
        window.scrollTo(0, scrollPosition);
        // 解绑scroll事件
        $(window).off('scroll', handleScrollUnlock);
    };

    // 滚动解锁触发函数
    const handleScrollUnlock = () => {
        unlockScroll();
    };

    var companyNameScene = new ScrollMagic.Scene({
        triggerElement: '#company-name',
        triggerHook: 1,
        reverse: false
    })
        .setTween(textAnimation)
        .setClassToggle('#company-name', 'visible')
        .addTo(controller)
        .on("start", function () {
            // 开始动画时锁定滚动
            lockScroll();
            // 绑定scroll事件,用户滚动时解锁
            $(window).on('scroll', handleScrollUnlock);
        });

    // 动画完成后自动解锁(可选,根据需求调整)
    textAnimation.eventCallback('onComplete', () => {
        unlockScroll();
    });
});

关键说明

  • 锁定滚动时记录了当前滚动位置,解锁时恢复,避免页面跳转。
  • 同时操作html和body确保在各浏览器中锁定生效。
  • 将scroll事件绑定移到动画start事件中,确保只有动画执行阶段的滚动才会触发解锁。
  • 可选的动画完成自动解锁,可根据业务需求决定是否保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:25:26