JS打造九宮格抽獎(jiǎng)的思路及實(shí)現(xiàn)代碼
前言
在如今的營(yíng)銷(xiāo)活動(dòng)中,抽獎(jiǎng)功能已經(jīng)成為提升用戶(hù)活躍度的標(biāo)配。尤其是“九宮格抽獎(jiǎng)”這種形式,因其視覺(jué)沖擊力強(qiáng)、交互簡(jiǎn)單、適配性好,被廣泛應(yīng)用于電商、社交、內(nèi)容平臺(tái)等各類(lèi)場(chǎng)景。本文將帶你從零開(kāi)始,使用 原生 JavaScript 實(shí)現(xiàn)一個(gè)可配置、可擴(kuò)展、動(dòng)畫(huà)流暢的九宮格抽獎(jiǎng)組件,支持運(yùn)營(yíng)人員通過(guò) JSON 配置獎(jiǎng)品信息,前端無(wú)需上線即可更新抽獎(jiǎng)內(nèi)容。

一、總體思路
1. 數(shù)據(jù)結(jié)構(gòu):獎(jiǎng)品配置 JSON 化
為了支持運(yùn)營(yíng)實(shí)時(shí)配置獎(jiǎng)品,我們將獎(jiǎng)品信息抽象為 JSON 格式:
[
{"id":1,"name":"iPhone","img":"http://cdn/1.png"},
{"id":2,"name":"現(xiàn)金50元","img":"http://cdn/2.png"},
{"id":3,"name":"HUAWEI","img":"http://cdn/3.png"},
{"id":4,"name":"現(xiàn)金10元","img":"http://cdn/4.png"},
{"id":5,"name":"謝謝參與","img":"http://cdn/5.png"},
{"id":6,"name":"手機(jī)優(yōu)惠券","img":"http://cdn/6.png"},
{"id":7,"name":"電腦優(yōu)惠券","img":"http://cdn/7.png"},
{"id":8,"name":"U盤(pán)","img":"http://cdn/8.png"}
]
優(yōu)點(diǎn):前端只負(fù)責(zé)展示和動(dòng)畫(huà),中獎(jiǎng)邏輯由后端控制,避免暴露算法,提升安全性。
2.核心思路
我們將整個(gè)抽獎(jiǎng)流程抽象為兩個(gè)核心步驟:
- 繪制獎(jiǎng)品視圖:無(wú)論使用 flex 、 grid 還是 absolute ,只要按順序渲染獎(jiǎng)品 DOM,順序即代表“跑道”順序。
- 動(dòng)畫(huà)高亮獎(jiǎng)品:通過(guò)setInterval控制高亮項(xiàng)的切換,只操作索引,不依賴(lài)具體坐標(biāo)或行列。
這種設(shè)計(jì)的好處是:
- 布局可隨意更換(九宮格、圓環(huán)、橫向跑道);
- 動(dòng)畫(huà)邏輯不變,復(fù)用性極高;
- 支持動(dòng)態(tài)增減獎(jiǎng)品數(shù)量,只需更新 JSON 和 CSS。
二、html骨架
<div class="main">
<div class="content-container">
<div class="prize-list">
<img src="./img/prize_1.png" alt="">
<span>IphoneX</span>
</div>
<div class="prize-list">
<img src="./img/prize_2.png" alt="">
<span>現(xiàn)金50元</span>
</div>
<div class="prize-list">
<img src="./img/prize_3.png" alt="">
<span>HUAWEI</span>
</div>
<div class="prize-list">
<img src="./img/prize_4.png" alt="">
<span>現(xiàn)金10元</span>
</div>
<div class="prize-list">
<img src="./img/prize_5.png" alt="">
<span>謝謝參與</span>
</div>
<div class="prize-list">
<img src="./img/prize_6.png" alt="">
<span>手機(jī)優(yōu)惠券</span>
</div>
<div class="prize-list">
<img src="./img/prize_7.png" alt="">
<span>電腦優(yōu)惠券</span>
</div>
<div class="prize-list">
<img src="./img/prize_8.png" alt="">
<span>U盤(pán)</span>
</div>
<!-- 中心內(nèi)容部分 -->
<div class="handler-container">
<div class="inner-container">
<img class="handler-left" src="./img/center_1.png" alt="">
<div class="handler-container-middle">
還可以抽獎(jiǎng) <span class="prize-number">0</span> 次
</div>
<div class="handler-container-btn"></div>
</div>
</div>
</div>
<div class="dialog-container">
<div class="dialog-main">
<div class="head">
<span class="title">溫馨提示</span>
<span class="close">×</span>
</div>
<div class="content">
每次抽獎(jiǎng)將消耗 8000 積分
</div>
<div class="dialog-main-footer">
<div class="button">再來(lái)一次</div>
</div>
</div>
</div>
</div>
三、js核心動(dòng)畫(huà)
var runGame = function () {
var random = Math.floor(Math.random() * 6000 + 3000)
timer = setInterval(function () {
random -= 200
if (random < 200) {
clearInterval(timer)
timer = null
openDialog()
return
}
currentIndex = ++index % prizeList.length
prizeList.forEach(function (node) {
node.classList.remove('active')
})
prizeList[currentIndex].classList.add('active')
}, 50)
}
技術(shù)亮點(diǎn):
- 索引循環(huán): ++index % prizeList.length 保證無(wú)限循環(huán);
- 時(shí)間遞減: random -= 200 模擬減速剎車(chē)效果;
- 動(dòng)畫(huà)與結(jié)果分離:動(dòng)畫(huà)結(jié)束后調(diào)用 openDialog() 顯示結(jié)果,邏輯清晰。
四、業(yè)務(wù)層
為了防止刷獎(jiǎng)和前端篡改,我們將“中獎(jiǎng)邏輯”放在后端:
流程如下:
- 前端點(diǎn)擊“抽獎(jiǎng)”按鈕;
- 請(qǐng)求后端接口,后端根據(jù)權(quán)重隨機(jī)計(jì)算出中獎(jiǎng)獎(jiǎng)品;
- 后端返回中獎(jiǎng)獎(jiǎng)品的 id 和對(duì)應(yīng)索引 stopIndex ;
- 前端根據(jù) stopIndex 播放動(dòng)畫(huà),最終高亮到對(duì)應(yīng)獎(jiǎng)品;
- 動(dòng)畫(huà)結(jié)束后彈出結(jié)果提示。
? 優(yōu)點(diǎn):
- 前端不暴露中獎(jiǎng)邏輯,安全性高;
- 動(dòng)畫(huà)與業(yè)務(wù)解耦,可復(fù)用性強(qiáng);
- 支持運(yùn)營(yíng)實(shí)時(shí)調(diào)整獎(jiǎng)品和中獎(jiǎng)概率,無(wú)需前端上線。
后續(xù)優(yōu)化建議
動(dòng)畫(huà)性能優(yōu)化:使用 Web Animations API 或 CSS Animation 替代 setInterval ;
防抖節(jié)流:防止用戶(hù)快速點(diǎn)擊觸發(fā)多次抽獎(jiǎng);
狀態(tài)管理:引入輕量狀態(tài)機(jī)(如 xstate)管理抽獎(jiǎng)流程;
音效與震動(dòng):增強(qiáng)用戶(hù)互動(dòng)體驗(yàn)。
化建議動(dòng)畫(huà)性能優(yōu)化:使用 Web Animations API 或 CSS Animation 替代 setInterval ;
防抖節(jié)流:防止用戶(hù)快速點(diǎn)擊觸發(fā)多次抽獎(jiǎng);
狀態(tài)管理:引入輕量狀態(tài)機(jī)(如 xstate)管理抽獎(jiǎng)流程;
音效與震動(dòng):增強(qiáng)用戶(hù)互動(dòng)體驗(yàn)。
總結(jié)
到此這篇關(guān)于JS打造九宮格抽獎(jiǎng)的思路及實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)JS九宮格抽獎(jiǎng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 原生JS實(shí)現(xiàn)九宮格抽獎(jiǎng)效果
- js實(shí)現(xiàn)九宮格抽獎(jiǎng)
- JS實(shí)現(xiàn)簡(jiǎn)單的九宮格抽獎(jiǎng)
- 原生JS實(shí)現(xiàn)九宮格抽獎(jiǎng)
- 用JS簡(jiǎn)單實(shí)現(xiàn)九宮格抽獎(jiǎng)的示例代碼
- JavaScript實(shí)現(xiàn)九宮格抽獎(jiǎng)
- JavaScript實(shí)現(xiàn)九宮格抽獎(jiǎng)功能的示例代碼
- JS實(shí)現(xiàn)簡(jiǎn)單九宮格抽獎(jiǎng)
- 原生JavaScript實(shí)現(xiàn)九宮格抽獎(jiǎng)
相關(guān)文章
原生JavaScript實(shí)現(xiàn)貪吃蛇游戲
這篇文章主要為大家詳細(xì)介紹了原生JavaScript實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
webpack實(shí)現(xiàn)熱更新(實(shí)施同步刷新)
本篇文章主要介紹了webpack實(shí)現(xiàn)熱更新(實(shí)施同步刷新),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
JavaScript實(shí)現(xiàn)鼠標(biāo)滑過(guò)圖片變換效果的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)鼠標(biāo)滑過(guò)圖片變換效果的方法,涉及javascript控制鼠標(biāo)事件及樣式變換的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
基于javascript實(shí)現(xiàn)右下角浮動(dòng)廣告效果
這篇文章主要介紹了基于javascript實(shí)現(xiàn)右下角浮動(dòng)廣告效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01
微信小程序搜索框樣式并實(shí)現(xiàn)跳轉(zhuǎn)到搜索頁(yè)面(小程序搜索功能)
這篇文章主要介紹了微信小程序搜索框樣式并實(shí)現(xiàn)跳轉(zhuǎn)到搜索頁(yè)面(小程序搜索功能),需要的朋友可以參考下2020-03-03
JavaScript中btoa和atob全局函數(shù)示例詳解
這篇文章主要給大家介紹了關(guān)于JavaScript中btoa和atob全局函數(shù)的相關(guān)資料,atob和btoa是window對(duì)象的兩個(gè)函數(shù),用來(lái)編碼解碼Base64,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-08-08

