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

歌曲切换时setTimeout延迟期间的动画异常问题

问题修复:歌曲切换时动画异常执行的问题

问题根源

  1. 歌曲切换时,之前设置的3秒延迟定时器未被清除,导致旧的动画任务仍会触发
  2. shiftingAnimation 函数通过闭包捕获了旧的 testWidth 值,即使切换歌曲后,旧动画执行时依然使用之前的宽度参数

修改后的代码

// 存储延迟定时器引用,用于后续清除
let animationTimer = null;

function wallpaperMediaPropertiesListener(event) {
    // 重置所有未完成的动画和定时器
    test.stop(true);
    clearTimeout(animationTimer);
    test.css('margin-left', 0);
    
    // 设置新歌曲标题并获取当前宽度
    test.text(event.title);
    const testWidth = test.outerWidth();
    const line1Width = $('#line1').width();
    
    // 更新克隆文本
    $('.test-copy').remove();
    if (testWidth > line1Width) {
        test.clone().css({'margin-left': gap, 'font-size': '1.05vh'}).removeClass().addClass('test-copy').insertAfter(test);
    }
    
    // 动画逻辑:传入当前宽度参数避免闭包旧值问题
    const speed = 5;
    function shiftingAnimation(currentWidth) {
        animationTimer = setTimeout(() => {
            test.animate({'margin-left': -(currentWidth + gap)}, {
                duration: Math.abs((currentWidth + gap) * 100 / speed),
                easing: 'linear',
                complete: function () {
                    test.css({'margin-left': 0});
                    // 循环时重新获取最新宽度,适配可能的动态变化
                    shiftingAnimation(test.outerWidth());
                }
            });
        }, 3000);
    }

    // 仅当新标题宽度超过容器时启动延迟动画
    if (testWidth > line1Width) {
        animationTimer = setTimeout(() => shiftingAnimation(testWidth), 3000);
    }
}

关键改动说明

  • 新增 animationTimer 变量存储延迟定时器引用,每次歌曲切换时强制清除未执行的延迟任务
  • 将 testWidth 作为参数传入 shiftingAnimation,彻底避免闭包捕获旧值的问题
  • 动画循环时重新获取最新的标题宽度,确保后续循环使用当前有效的尺寸
  • 提取 line1Width 变量,减少重复DOM查询次数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:12:41