如何实现游戏结束/重置后动画每次触发,而非仅首次生效?
如何实现游戏结束/重置后动画每次触发,而非仅首次生效?
我仔细看了你的代码,问题出在模态框动画的触发逻辑和CSS动画的写法上,下面一步步给你拆解和解决:
问题根源分析
- 属性切换未清理旧属性:你在
gameOver里给modal加open属性,重置时加close属性,但没有移除对立的属性。这会导致modal同时存在open和close两个属性,浏览器无法正确检测到属性的“变化”,自然不会重复触发动画。 - CSS动画里用
display属性干扰流程:display是瞬间切换的离散属性,和opacity的平滑过渡冲突,容易导致动画触发异常,甚至直接跳过动画。
解决方案:分两步修复
第一步:修正JS里的模态框属性切换逻辑
每次切换状态时,先移除对立属性,再添加新属性,让浏览器明确感知到属性的变化:
// 修改gameOver函数 const gameOver = () => { // ... 保留原有其他代码 modal.removeAttribute("close"); // 先移除close属性,避免属性冲突 modal.setAttribute("open", ""); // ... 保留原有其他代码 } // 修改resetGame函数 const resetGame = () => { // ... 保留原有其他代码 modal.removeAttribute("open"); // 先移除open属性,避免属性冲突 modal.setAttribute("close", ""); // ... 保留原有其他代码 }
第二步:优化CSS动画,移除display设置
把@keyframes里的display全部删掉,只用opacity控制透明度变化,同时调整交互逻辑:
.modal { position: fixed; background: rgb(255, 252, 252); box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; color: white; top: 20%; left: 50%; transform: translateX(-50%); text-align: center; font-size: 2rem; padding: 0.5em; width: 30em; border-radius: 2px; opacity: 0; pointer-events: none; z-index: 1; } .modal[open] { animation: modal-fade-in 500ms; animation-fill-mode: forwards; pointer-events: auto; /* 模态框显示时允许点击交互 */ } .modal[close] { animation: modal-fade-out 500ms; animation-fill-mode: forwards; } /* 移除@keyframes里的display设置 */ @keyframes modal-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes modal-fade-out { 0% { opacity: 1; } 100% { opacity: 0; } }
可选优化:动画结束后彻底隐藏模态框
如果希望淡出动画结束后完全隐藏模态框(避免透明状态下占空间),可以加个动画结束监听:
// 修改resetBtn的监听逻辑,避免重复绑定事件 resetBtn.addEventListener("click", () => { resetGame(); // 监听淡出动画结束事件 const handleFadeOutEnd = (e) => { if (e.animationName === 'modal-fade-out') { modal.removeAttribute("close"); modal.style.display = 'none'; modal.removeEventListener('animationend', handleFadeOutEnd); // 用完就移除监听 } }; modal.addEventListener('animationend', handleFadeOutEnd); }); // 同时在gameOver里先显示模态框再触发动画 const gameOver = () => { // ... 保留原有其他代码 modal.style.display = 'block'; modal.removeAttribute("close"); modal.setAttribute("open", ""); // ... 保留原有其他代码 }
这样修改后,每次游戏结束和重置时,模态框的淡入淡出动画都会正常触发,不会再出现首次生效后失效的问题啦。
备注:内容来源于stack exchange,提问作者zdravko93




