当前位置: 首页 > news >正文

【JS案例】JS实现积分抽奖(内附源码)

JS案例·实现积分抽奖

🌟效果展示  

🌟HTML结构

🌟CSS样式

🌟实现思路

🌟具体实现

1.定义抽奖次数渲染

 2.点击抽奖按钮,实现滚动抽奖效果

 3.弹窗处理

🌟完整代码 

🌟写在最后 


🌟效果展示  

   视频转gif还是有点卡顿掉帧,实际效果非常流畅噢,文末有源码,可以带走玩玩! 


 

🌟HTML结构

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>随机抽奖</title><link rel="stylesheet" href="./css/index.css">
</head><body><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>现金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>现金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>手机优惠券</span></div><div class="prize-list"><img src="./img/prize_7.png" alt=""><span>电脑优惠券</span></div><div class="prize-list"><img src="./img/prize_8.png" alt=""><span>U盘</span></div><!-- 中心内容部分 --><div class="handler-container"><div class="inner-container"><img class="handler-left" src="./img/center_1.png" alt=""><div class="handler-container-middle">还可以抽奖 <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">&times;</span></div><div class="content">每次抽奖将消耗 8000 积分</div><div class="dialog-main-footer"><div class="button">再来一次</div></div></div></div></div><script src="./js/index.js"></script>
</body></html>

 

🌟CSS样式

* {margin: 0;padding: 0;
}.main {height: 546px;background-image: url('../img/banner-bg.jpg');position: relative;
}.content-container {position: absolute;width: 874px;height: 458px;background-image: url('../img/bg.png');left: 50%;top: 50%;transform: translate(-50%, -50%);
}.prize-list {width: 270px;height: 100px;position: absolute;width: 270px;height: 100px;padding: 5px;box-sizing: border-box;text-align: center;background: #622230;border: 1px solid #722536;border-radius: 5px;
}.prize-list>img {max-height: 75px;position: absolute;left: 30px;top: 15px;
}.prize-list>span {font-size: 19px;color: #ffb100;font-weight: bold;position: absolute;left: 102px;top: 36px;width: 164px;
}.prize-list:nth-child(1) {top: 22px;left: 26px;
}.prize-list:nth-child(2) {top: 22px;left: 302px;
}.prize-list:nth-child(3) {top: 22px;right: 26px;
}.prize-list:nth-child(4) {top: 129px;right: 26px;width: 100px;height: 200px;
}.prize-list:nth-child(4)>img,
.prize-list:nth-child(8)>img {left: 50%;transform: translateX(-50%);
}.prize-list:nth-child(4)>span,
.prize-list:nth-child(8)>span {left: 50%;transform: translateX(-50%);top: auto;bottom: 36px;
}.prize-list:nth-child(5) {bottom: 22px;right: 26px;
}.prize-list:nth-child(5)>img {top: 20px;
}.prize-list:nth-child(6)>img,
.prize-list:nth-child(7)>img {top: 25px;
}.prize-list:nth-child(6) {bottom: 22px;left: 302px;
}.prize-list:nth-child(7) {bottom: 22px;left: 26px;
}.prize-list:nth-child(8) {top: 129px;left: 26px;width: 100px;height: 200px;
}.handler-container {width: 614px;height: 198px;background-image: url('../img/middle-bg.png');position: absolute;left: 130px;top: 130px;display: table;
}.inner-container {display: table-cell;vertical-align: middle;padding: 0 20px;
}.handler-left {float: left;vertical-align: middle;
}.handler-container-middle {float: left;color: #ffd200;font-size: 30px;font-weight: bold;margin: 17px 0 0 18px;
}.handler-container-btn {width: 210px;height: 102px;background-image: url('../img/btn.png');float: right;cursor: pointer;
}.active {background-color: #ffd100;
}.active>span {color: #470c1b;
}/* 对话框样式 */.dialog-container {position: fixed;width: 100%;height: 100%;left: 0;top: 0;background-color: rgba(0, 0, 0, .5);display: none;
}.dialog-main {width: 400px;background-color: #fff;position: absolute;left: 50%;top: 30%;transform: translate(-50%, -50%);box-sizing: border-box;
}.dialog-main>.head {height: 50px;line-height: 50px;background-color: #e99c3d;border-bottom: 1px solid #ddd;box-sizing: border-box;padding: 0 20px;
}.dialog-main>.head>.title {float: left;color: #fff;font-size: 18px;
}.dialog-main>.head>.close {float: right;color: #fff;font-size: 42px;cursor: pointer;
}.dialog-main-footer {text-align: right;margin: 20px;
}.dialog-main>.content {text-align: center;margin: 20px;color: #622230;font-weight: bold;font-size: 20px;
}.dialog-main-footer>.button {background-color: #fca825;height: 28px;cursor: pointer;display: inline-block;line-height: 28px;color: #fff;padding: 0 10px;border-radius: 3px;
}

 

🌟实现思路

在敲完上面HTML文件和CSS文件后可以看到下图效果(图片素材及完整代码文末可下载):

接下来我们需要实现的就是以下步骤:

1: 定义抽奖次数渲染

  1-1 获取DOM元素

  1-2 定义剩余的抽奖次数

2: 点击抽奖按钮,实现滚动抽奖效果

  2-1 获取点击按钮 ,绑定点击事件

  2-2 为每一个list选项添加类名,实现高亮状态

  2-3 定义当前高亮的列表项索引值

  2-4 使用定时器实现滚动效果

  2-5 使用随机数定义停止条件

3: 弹窗处理

  3-1 打开弹窗.显示中奖信息(处理未中奖时的弹窗提示内容)

  3-2 打开弹窗的同时,减少剩余的抽奖次数

  3-3 关闭按钮的事件绑定

  3-4 再来一次按钮事件绑定

那么就一步步开始实现吧!


 

🌟具体实现

1.定义抽奖次数渲染

获取DOM元素并在入口函数中赋值,这里默认赋值5次。

(function () {
let number = 5
let prizeNumber = document.querySelector('.prize-number')
let init = function () {prizeNumber.innerHTML = number}
init()
})()

 2.点击抽奖按钮,实现滚动抽奖效果

获取点击按钮 ,绑定点击事件

let startBtn = document.querySelector('.handler-container-btn')
startBtn.addEventListener('click', onStartBtnClick)
let onStartBtnClick = function () {
}

 接下来要给每一个list选项添加类名,实现高亮状态,那用什么方式来添加类名呢,可以看下图,目前这种方法也是觉大部分浏览器兼容,很好用:

document.querySelectorAll('.prize-list')[0].classList.add('active')

 当点击开始抽奖按钮时,将执行一个定时器,这时高亮也将向前跳一步,其实就是给索引0加高亮-》清除所有高亮-》给索引1加高亮-》清除所有高亮 -》...如此就实现了跳向下一个的效果。

let prizeList = document.querySelectorAll('.prize-list')
let index = -1
let timer = null
let onStartBtnClick = function () {if (timer) returnindex = -1if (number === 0) returnrunGame()
}let runGame = function () {// 生成随机数控制定时器let random = Math.floor(Math.random() * 6000 + 3000)timer = setInterval(function () {random -= 200if (random < 200) {clearInterval(timer)timer = nullreturn}currentIndex = ++index % prizeList.lengthprizeList.forEach(function (node) {node.classList.remove('active')})prizeList[currentIndex].classList.add('active')}, 50)
}

 3.弹窗处理

抽奖结束处理弹窗效果


let openDialog = function () {prizeNumber.innerHTML = --numberif (number === 0) {document.querySelector('.dialog-main-footer .button').innerHTML = '确定'}dialogContainer.style.display = 'block'if (currentIndex === 4) {prizeContent.innerHTML = '很遗憾您没有中奖'} else {prizeContent.innerHTML = '恭喜您获得' + document.querySelector('.active span').innerHTML}
}

接下来就是一些细节处理与函数封装,就不细讲了,源码在下面。


 

🌟完整代码 

HTML和CSS文件就是上面代码无变化,下面是index.js文件:

/* 
1: 定义抽奖次数渲染1-1 获取DOM元素1-2 定义剩余的抽奖次数
2: 点击抽奖按钮,实现滚动抽奖效果(复杂度高)2-1 获取点击按钮 ,绑定点击事件2-2 为每一个list选项添加类名,实现高亮状态2-3 定义当前高亮的列表项索引值2-4 使用定时器实现滚动效果2-5 使用随机数定义停止条件
3: 弹窗处理 3-1 打开弹窗.显示中奖信息(处理未中奖时的弹窗提示内容)3-2 打开弹窗的同时,减少剩余的抽奖次数3-3 关闭按钮的事件绑定3-4 再来一次按钮事件绑定 */(function () {let startBtn = document.querySelector('.handler-container-btn')let prizeList = document.querySelectorAll('.prize-list')let dialogContainer = document.querySelector('.dialog-container');let prizeContent = document.querySelector('.dialog-container .content')let index = -1let timer = nulllet number = 5let currentIndex = nulllet closeBtn = document.querySelector('.close')let confirmBtn = document.querySelector('.dialog-main-footer .button')let prizeNumber = document.querySelector('.prize-number')let init = function () {prizeNumber.innerHTML = numberinitEvent()}let initEvent = function () {startBtn.addEventListener('click', onStartBtnClick)closeBtn.addEventListener('click', onCloseBtnClick)confirmBtn.addEventListener('click', onConfirmBtnClick)}let onStartBtnClick = function () {if (timer) returnindex = -1if (number === 0) returnrunGame()}/* 关闭弹窗 */let onCloseBtnClick = function () {dialogContainer.style.display = 'none'}let onConfirmBtnClick = function () {index = -1dialogContainer.style.display = 'none'if (number === 0 || timer) returnrunGame()}let runGame = function () {let random = Math.floor(Math.random() * 6000 + 3000)timer = setInterval(function () {random -= 200if (random < 200) {clearInterval(timer)timer = nullopenDialog()return}currentIndex = ++index % prizeList.lengthprizeList.forEach(function (node) {node.classList.remove('active')})prizeList[currentIndex].classList.add('active')}, 50)}let openDialog = function () {prizeNumber.innerHTML = --numberif (number === 0) {document.querySelector('.dialog-main-footer .button').innerHTML = '确定'}dialogContainer.style.display = 'block'if (currentIndex === 4) {prizeContent.innerHTML = '很遗憾您没有中奖'} else {prizeContent.innerHTML = '恭喜您获得' + document.querySelector('.active span').innerHTML}}init()
})()

完整源码及图片素材免费下载地址:点击免费下载 


 

🌟写在最后 

本专栏将持续更新原生JS案例,提供一些工作中也能用上的一些小案例,详细讲解分析,提升JS开发水平与开发思路的积累,如果文中出现有瑕疵的地方各位通过评论或者私信联系我,我们一起进步,有兴趣的伙伴可以订阅一下:点击关注JS经典案例专栏

相关文章:

【JS案例】JS实现积分抽奖(内附源码)

JS案例实现积分抽奖 &#x1f31f;效果展示 &#x1f31f;HTML结构 &#x1f31f;CSS样式 &#x1f31f;实现思路 &#x1f31f;具体实现 1.定义抽奖次数渲染 2.点击抽奖按钮,实现滚动抽奖效果 3.弹窗处理 &#x1f31f;完整代码 &#x1f31f;写在最后 &#x1f3…...

angular抛出 ExpressionChangedAfterItHasBeenCheckedError错误分析

当变更检测完成后又更改了表达式值时&#xff0c;Angular 就会抛出 ExpressionChangedAfterItHasBeenCheckedError 错误。Angular 只会在开发模式下抛出此错误。 在开发模式下&#xff0c;Angular 在每次变更检测运行后都会执行一次附加检查&#xff0c;以确保绑定没有更改。这…...

动态链接库的__declspec(dllexport)关键字的概念

在 Windows 操作系统下&#xff0c;创建一个动态链接库&#xff08;DLL&#xff09;项目时&#xff0c;您需要通过 __declspec(dllexport) 关键字来显式地标记希望在 DLL 中 公开 的函数、类、变量等符号。这是因为在默认情况下&#xff0c;编译器会将函数和符号视为 私有&…...

群晖NAS:DS Video、Jellyfin等视频电影电视剧海报、背景墙搜刮器

群晖NAS&#xff1a;DS Video、Jellyfin等视频电影电视剧海报、背景墙搜刮器 本文只使用豆瓣插件方式&#xff0c;系统默认的 The Movie Database 好注册&#xff0c;但是授权码输入后域名不通过&#xff0c;很麻烦。 1、插件地址&#xff1a; https://www.aliyundrive.com/s…...

WEBGL(3):鼠标动态绘制点

1 实现思路 绘制单个点鼠标事件监听点击事件将点推送到数组中绘制数组中所有点 2 实现代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge&…...

Sass基础

Sass基础 简介 Sass是一种stylesheet语言&#xff0c;可以被编译成CSS。Sass允许你使用诸如variabels&#xff0c;nested rules&#xff0c;mixins&#xff0c;functions等等语法&#xff0c;这些都将在本篇的接下来进行讲解。 因为之前一直学的后端&#xff0c;前端只是因为…...

Java中的消息队列有哪些?

在Java中&#xff0c;有几种常见的消息队列实现&#xff0c;包括&#xff1a; Apache Kafka&#xff1a;一个分布式流处理平台&#xff0c;具有高吞吐量、可持久化、可扩展等特点。 RabbitMQ&#xff1a;一个开源的消息代理&#xff0c;实现了AMQP&#xff08;高级消息队列协议…...

多维时序 | Matlab实现GRU-Adaboost和GRU多变量时间序列预测对比

多维时序 | Matlab实现GRU-Adaboost和GRU多变量时间序列预测对比 目录 多维时序 | Matlab实现GRU-Adaboost和GRU多变量时间序列预测对比预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实现GRU-Adaboost和GRU多变量时间序列预测对比 模型描述 M…...

测试用例编写规范参考

章节目录&#xff1a; 一、规范目的二、模块划分三、颗粒度规范四、编写规范五、具体分项5.1 用例标题5.2 前置条件5.3 操作步骤5.4 预期结果 六、用例维护七、结束语 一、规范目的 规范合理&#xff0c;可执行性。一定要保证高可读性。 二、模块划分 同级别、同等级功能点。…...

unity3d:功能验证,收集开源项目的工程合集

unity3d功能验证&#xff0c;和收集开源项目的工程合集 目录持续更新地址 【腾讯文档】UnityForTest目录 https://docs.qq.com/doc/DWm9HSkVhTGdyUUVo 源码 https://github.com/luoyikun/UnityForTest 动画 创建骨骼动画 BoneAnimation场景 代码创建Mesh&#xff0c;骨骼…...

plotly_beforehover 用法:

在Plotly.js中&#xff0c;plotly_beforehover是在鼠标悬停在数据点上之前触发的回调事件。它的主要作用是在鼠标悬停事件发生前做一些准备工作。 plotly_beforehover事件是与图表对象绑定的&#xff0c;可以通过调用on方法来绑定事件处理程序。下面是一个示例代码&#xff1a…...

利用 AI 赋能云安全,亚马逊云科技的安全技术创新服务不断赋能开发者

文章分享自亚马逊云科技 Community Builder&#xff1a;李少奕 2023年6月14日&#xff0c;一年一度的亚马逊云科技 re:Inforce 全球大会在美国安纳海姆落下了帷幕。re:Inforce 是亚马逊云科技全球最大的盛会之一&#xff0c;汇集了来自全球各地的安全专家&#xff0c;共同学习、…...

18. 填坑Ⅰ

Description 又是北湖深坑&#xff0c;惊不惊喜&#xff0c;意不意外&#xff1f;&#xff01; 觉得用水填湖太没意思了&#xff0c;用石头填坑多有意思。 假设北湖的地面还是一维的&#xff0c;每一块宽度都为1&#xff0c;高度是非负整数&#xff0c;用一个数组来表示。 现提…...

CSS 实现平面圆点绕椭圆动画

前言 &#x1f44f;CSS实现平面圆点绕椭圆动画,速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现原理 transform-style&#xff1a;CSS 属性 transform-style 设置元素的子元素是位于 3D 空间中还是平面中。如果选择平面&#xf…...

docker login : x509: certificate signed by unknown authority

一. 背景 docker login 登录harbor镜像仓库报错. [rootmaster01 sloth]# docker login docker.harbor.master01.com Username: bigdata Password: Error response from daemon: Get https://docker.harbor.master01.com/v2/: x509: certificate signed by unknown authority …...

金蝶云星空二开,插件查看工具

可查询单据上挂载的系统原有插件、二开插件及插件类型 1.支持模糊查询单据列表 2.支持项目与账套二开插件对比 3.支持金蝶不同账套之间对比差异 操作步骤&#xff1a; 1.登陆界面&#xff0c;选择金蝶云管理中心账套登录获取账套列表&#xff1b; 2.单一标识查询&#xff1a;…...

error: ‘std::_hypot‘ has not been declared using std::hypot;

Cmake 使用qt的编译器 编译opencv时 执行mingw32-make时出现了错误 本质原因就是 _hypot 没有声明。所以找到对应的文件声明一下 就行了。 E:\*****\Qt5.14.1\Tools\mingw730_64\lib\gcc\x86_64-w64-mingw32\7.3.0\include\c 下面的math.h 文件。 可以看到这个文件有一个…...

介绍 Apache Spark 的基本概念和在大数据分析中的应用。

Apache Spark 是一个快速的开源大数据处理引擎&#xff0c;可以用于大数据处理、机器学习、图形计算等领域。它可以在多种计算环境中运行&#xff0c;包括独立模式、YARN、Mesos、Kubernetes等云计算平台。 Spark基于RDD&#xff08;Resilient Distributed Datasets&#xff0…...

Java设计模式:四、行为型模式-09:模板模式

文章目录 一、定义&#xff1a;模板模式二、模拟场景&#xff1a;模板模式三、改善代码&#xff1a;模板模式3.0 引入依赖3.1 工程结构3.2 模板模式结构图3.3 爬取商品生成海报实现3.3.1 HTTP获取连接类3.3.2 定义执行顺序的抽象类3.3.3 当当爬取抽象实现类3.3.4 京东爬取抽象实…...

【前端】Vue2 脚手架模块化开发 -快速入门

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理Vue2 脚手架模块化开发 &#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&#x…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...