歌曲切换时setTimeout延迟期间的动画异常问题
问题修复:歌曲切换时动画异常执行的问题
问题根源
- 歌曲切换时,之前设置的3秒延迟定时器未被清除,导致旧的动画任务仍会触发
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
相关产品推荐
相关产品推荐

