模态框animationiteration延迟问题:requestAnimationFrame是否可行?
解决模态框动画透明度不稳定的问题
嘿,你的问题我完全get到了——因为animationiteration事件的触发时机和浏览器渲染周期不同步,导致JS有时候没及时暂停动画,才出现了透明度忽高忽低的不稳定情况。requestAnimationFrame确实是个靠谱的解决方案,它能让你的代码精准贴合浏览器的重绘节奏,完美避开时机差的坑。
为什么会出现这个问题?
你设置的动画是fade-before 0.3s ease-out 0s 2 alternate-reverse,也就是会反向交替播放两次。当点击打开模态框时,动画开始执行,但animationiteration事件要等第一次迭代(0.3秒后)才触发,要是JS的事件监听绑定稍晚,或者浏览器渲染队列有延迟,就会错过暂停时机,导致模态框停在动画中间的透明度状态。
用requestAnimationFrame修复的具体方案
我们可以利用requestAnimationFrame让暂停动画和设置透明度的操作,在下一次浏览器重绘前执行,确保时机精准。修改你的JS代码如下:
var oLay = document.getElementById('yt-modal-cont'); var modalToggle = document.getElementById('vids'); function openModal() { if (!modalToggle.checked) return; // 先重置动画状态,确保每次打开都是从头开始 oLay.style.display = 'block'; oLay.style.animation = 'none'; // 用requestAnimationFrame确保样式更新后再重新启动动画 requestAnimationFrame(() => { oLay.style.animation = 'fade-before 0.3s ease-out 0s 2 alternate-reverse'; // 再用一次requestAnimationFrame,在下一帧暂停动画并强制锁定透明度 requestAnimationFrame(() => { oLay.style['animation-play-state'] = 'paused'; oLay.style.opacity = '1'; }); }); } modalToggle.addEventListener('click', openModal);
更简洁的替代方案:用Transition代替Animation
其实对于这种单次的显隐动画,用CSS Transition会比Animation更直观,也不容易出现事件时机的问题。你可以这样调整:
- 修改CSS:
#yt-modal-cont { opacity: 0; transition: opacity 0.3s ease-out; display: none; } #yt-modal-cont.active { opacity: 1; }
- 简化JS逻辑:
var oLay = document.getElementById('yt-modal-cont'); var modalToggle = document.getElementById('vids'); modalToggle.addEventListener('click', () => { if (modalToggle.checked) { oLay.style.display = 'block'; // 用requestAnimationFrame确保display生效后再添加active类,触发过渡 requestAnimationFrame(() => { oLay.classList.add('active'); }); } else { oLay.classList.remove('active'); // 等待过渡动画结束后再隐藏容器 setTimeout(() => { oLay.style.display = 'none'; }, 300); } });
这种方式不需要监听动画迭代事件,逻辑更清晰,也能彻底解决你遇到的不稳定问题。
内容的提问来源于stack exchange,提问作者panrosmithe
相关产品推荐
相关产品推荐

