九宫格抽奖需用grid布局+类名切换实现高亮/放大效果,而非rotate旋转;应采用伪随机滚动加真随机落点算法,并处理移动端事件、本地存储等细节。

九宫格抽奖不是转盘,别用 rotate 硬套
很多人一看到“抽奖动画”就下意识往 CSS transform: rotate() 上靠,结果做出来是转盘,不是九宫格。九宫格本质是 3×3 网格中某个格子高亮/放大/闪动,再配合顺序点亮或随机跳转的视觉节奏——它不依赖中心旋转,而是靠 grid 布局 + animation 或 JS 控制类名切换。
常见错误现象:rotate(360deg) 转一整页、格子跟着歪、点击后位置错乱、无法精准停在目标格。
- 用
display: grid定义容器,设grid-template-columns: repeat(3, 1fr) - 每个奖品格用独立
<div>,加统一 class 如 <code>cell,中奖格额外加active - 动画用
@keyframes pulse或scale(1.2) box-shadow,避免影响布局流 - 用
let current = 0记录当前高亮格索引,定时器每 100ms 更新一次 - 前 15 次用
(current + Math.floor(Math.random() * 3) + 1) % 9跳跃,制造混乱感 - 最后 3–5 次改用预设路径数组,比如
[2, 5, 8, 7, 6],确保终点可控 - 中奖格确定后,清空定时器,再执行一次
classList.add('winner') - 按钮监听
touchstart和click双事件,用event.preventDefault()阻止默认行为 - 加状态锁:
if (isRunning) return,抽奖开始后禁用按钮,结束后恢复 - 避免给
cell格子本身绑touchstart,只操作控制按钮,否则格子间缝隙会导致误失焦 - 存之前必须
JSON.stringify(historyArray),取出来立刻JSON.parse() - 加 try/catch,防止历史数据损坏导致整个页面报错:
try { ... } catch(e) { historyArray = [] } - 单条记录建议含字段:
{ name: '张三', prize: 'iPad', time: Date.now() },方便后续按时间倒序展示
Math.random() 直接选格会假随机,要加防连抽逻辑
纯靠 Math.random() * 9 | 0 生成 0–8 下标,连续抽奖时容易重复或集中某几格,用户一眼看出“不真”。真实抽奖需模拟物理停顿感:先快速滚动(伪随机),再减速落点(真随机锁定)。
使用场景:按钮点击触发,需支持暂停/重置;多人同时抽奖时不能共享同一随机种子。
移动端点击失效?检查 touchstart 和 preventDefault
PC 端点按钮好好的,手机上要点两下才触发,甚至完全无响应——大概率是事件绑定用了 click,但 iOS Safari 对快速点击有 300ms 延迟,且某些 CSS 触发了默认行为拦截。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
性能影响:加 touchstart 后若不做节流,快速连点可能启动多轮抽奖。
中奖数据没存本地?localStorage 存的是字符串,别直接塞对象
想记录“张三抽中 iPad”,刷新页面就没了。有人直接 localStorage.setItem('history', historyArray),结果存进去是 toString() 后的逗号分隔字符串,取出来根本没法遍历。
兼容性影响:IE8+ 支持 localStorage,但不支持 JSON.stringify 的部分特性(如 undefined 自动丢弃),需兼容处理。
九宫格抽奖真正的复杂点不在动画,而在“停在哪”和“怎么让人信”。随机算法藏在哪、中奖是否可复现、历史是否可查——这些细节比转几圈更决定用户愿不愿意再点一次。










