You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何实现游戏结束/重置后动画每次触发,而非仅首次生效?

如何实现游戏结束/重置后动画每次触发,而非仅首次生效?

我仔细看了你的代码,问题出在模态框动画的触发逻辑和CSS动画的写法上,下面一步步给你拆解和解决:

问题根源分析

  1. 属性切换未清理旧属性:你在gameOver里给modal加open属性,重置时加close属性,但没有移除对立的属性。这会导致modal同时存在openclose两个属性,浏览器无法正确检测到属性的“变化”,自然不会重复触发动画。
  2. 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

火山引擎 最新活动