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

如何在JavaScript中结合HTML元素与CSS @keyframes实现动画?

实现石头剪刀布手型切换动画(纯Div、无图片)

问题分析

你遇到的核心问题:

  • CSS @keyframes仅能控制元素的样式属性(如尺寸、位移、透明度等),无法直接嵌入或切换HTML结构,所以用它实现手型切换是行不通的。
  • 直接用普通循环切换数组元素时,JavaScript单线程特性会阻塞页面渲染,导致动画卡顿,最终直接跳转到结果。

解决方案

使用setInterval创建高频切换的定时器,让浏览器能及时渲染每一次手型变化,形成流畅动画;5秒后清除定时器并设置最终随机手型。

修改后的完整代码

HTML(保留原有结构)

<h1 id="pageTitle">Rock - Paper - Scissors!</h1>

<div class="container">
  <div class="box" id="box"></div>
  <span></span> 
</div> 
<button class="button" id="Shoot" onclick="shoot()">RPS Shoot!</button>

JavaScript

var rpsArr = [
  "<div class='rock'><div class='rockhand rockPointerFinger'></div><div class='rockhand rockMiddleFinger'></div><div class='rockhand rockRingFinger'></div><div class='rockhand rockPinkyFinger'></div><div class='rockhand rockThumb'></div><div class='rockhand rockPalm'></div></div>",
  '<div class="scissors scissorsPointerFinger"></div><div class="scissors scissorsMiddleFinger"></div><div class="scissors scissorsRingFinger"></div><div class="scissors scissorsPinkyFinger"></div><div class="scissors scissorsThumb"></div><div class="scissors scissorsPalm"></div>', 
  '<div class="paper paperPointerFinger"> <div class="paperPointBackground"></div></div><div class="paper paperMiddleFinger"><div class="paperMidBackground"></div></div><div class="paper paperRingFinger"><div class="paperRingBackground"></div></div><div class="paper paperPinkyFinger"><div class="paperPinkyBackground"></div></div> <div class="paper paperThumb"><div class="paperThumbBackground"></div></div><div class="paper paperPalm"><div class="paperPalmBackground"></div></div>'
];

const box = document.getElementById("box");
const shootBtn = document.getElementById("Shoot");

function shoot() {
  // 禁用按钮,防止重复触发动画
  shootBtn.disabled = true;
  // 手型切换间隔(毫秒),值越小动画越流畅
  const switchInterval = 100;
  // 总动画时长(5秒)
  const totalDuration = 5000;
  let currentHandIndex = 0;

  // 启动定时器,循环切换手型
  const animationTimer = setInterval(() => {
    currentHandIndex = (currentHandIndex + 1) % rpsArr.length;
    box.innerHTML = rpsArr[currentHandIndex];
  }, switchInterval);

  // 到达时长后停止动画,设置最终随机结果
  setTimeout(() => {
    clearInterval(animationTimer);
    // 随机选择最终显示的手型
    const finalHandIndex = Math.floor(Math.random() * rpsArr.length);
    box.innerHTML = rpsArr[finalHandIndex];
    // 恢复按钮可用状态
    shootBtn.disabled = false;
  }, totalDuration);
}

关键说明

  1. 定时器逻辑:setInterval每隔指定毫秒切换一次手型,浏览器能逐帧渲染变化,避免卡顿。
  2. 按钮禁用:防止用户在动画运行中重复点击,避免多个定时器同时执行。
  3. 最终结果:5秒后清除定时器,随机选择一个手型作为最终结果,确保每次结果不可预测。
  4. 样式依赖:需确保你已通过CSS正确定义.rock、.scissors、.paper及其子元素的样式,保证手型正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:25:03