『 JS真好玩』关于我用原生 JS 实现一个有趣的抽奖程序😁
前言
很久都没有用原生 JS
写过东西了,目前在实际开发中,基本都是用到现成的框架。刚好最近在小破站又学到了一个新的效果,同时也为了不遗忘原生 JS
相关的操作,今天我们就一起来使用原生 JS
开发一个抽奖的小程序。老规矩还是先看一下最终的成品吧,如下:
这个抽奖的程序很简单,刚打开的时候会自动旋转进行抽奖,当我们按下键盘的空格键时就会自动抽出当前的中奖人员。下面就让我们一起来看一下这个程序是如何实现的吧!
圆盘
首先我们需要先实现一下这个圆盘,这里只使用了简单的 html
和 css
,让我们一起来看一下相关的代码,如下:
<div class="list"></div>
html
的内容很简单,只有一个 div
标签。我们再一起来看一下相关的 css
代码,如下:
*{
margin: 0;
padding: 0;
}
body {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #333;
overflow: hidden;
}
.list {
width: 400px;
height: 400px;
border: 1px solid #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
上述的 css
就实现了一个圆,接下来我们需要设置一下在圆中右侧的中奖红三角,也是用 css
来实现的。那么你知道如何用纯 css
实现一个三角吗?让我们一起来看一下代码:
.list::after {
content: '';
position: absolute;
width: 0;
height: 0;
border-width: 6px;
border-style: solid;
border-color: transparent transparent transparent red;
right: 0;
}
在 css
中,我们可以通过 border
来创建一个三角形,只需要给对于的元素设置它的 width
和 height
属性为 0,然后设置对应的 border
属性,如果你希望设置一个向右的三角形,那么你可以通过设置 border-color
来实现。border-color
可以设置四个值,这四个值分别对应的就是边框的上右下左,我们只需设置上右下三个边的颜色为透明的,给左边的边设置一个颜色,就能实现向右的三角行。同理,如果改变其中某个边的颜色,就能实现朝向其它方向的三角形,大家可以尝试一下。
实现了指向中奖人员的名单,我们接下来就实现一下圆圈周围的人名样式,相关代码如下:
.list::before {
content: attr(data);
position: absolute;
color: #1e90ff;
font-size: 64px;
}
.list span {
color: #fff;
position: absolute;
width: calc(100% + 120px);
height: 20px;
text-align: right;
transition: 0.01s linear;
user-select: none;
}
我们给 list
的 before
伪类添加了一个 attr(data)
值,这是为了后续在圆的中心显示当前指向中奖的人的名字,这个属性需要配合 JS
中的 setAttributes
方法一起使用,后续遇到再说这里。
静态的圆已经画好了,接下来我们就需要用到原生 JS
来实现人名的动态生成和抽奖了。
抽奖
因为我们这里是用原生 JS 来实现这个效果,因此我们所有的操作方法都是原生的方法。首先我们需要获取到 list 这个对象,我们可以通过 document.getElementsByClassName()
或 document.querySelector()
来获取元素,这里我们用 document.querySelector()
,因为它选取到的元素只是一个,如果用 document.getElementsByClassName()
,我们还需要选择第一个元素。这两个 API 的区别,有想了解的童鞋可以到 MDN
官网去进行查看。
选择了 list
元素后,我们就需要动态的插入一些 span
标签了,这些 span
标签就是我们在圆周围展示的人名,而人名我们也是随机生成的。下面我们一起来看一下初始的代码,这里使用的也是面向对象的方式,代码如下:
class Lottery {
constructor() {
this.list = document.querySelector('.list');
this.randomSurnam = ["赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "褚", "卫", "蒋", "沈", "韩", "杨"];
this.randomName = ["泽", "桐", "梓", "一", "宁", "梅", "生", "平", "明", "涵", "韵", "宸", "坤", "华", "星", "家"];
this.names = [];
this.run = true;
this.deg = 0;
this.slow = 0;
}
}
在 Lottery 类的构造函数中,我们定义了初始的属性,其中定义了一个随机的姓的数组和随机的名字的数字,我们通过这两个数字来动态的生成随机名字,接下来有一个初始化的方法,用于生成随机名字,代码如下:
class Lottery {
constructor() {
//...other code
this.init();
}
init() {
for (let i = 0; i < 40; i++) {
this.names.push(
this.randomSurnam[Math.random() * this.randomSurnam.length | 0] +
this.randomName[Math.random() * this.randomName.length | 0] +
this.randomName[Math.random() * this.randomName.length | 0]
)
}
for (let key in this.names) {
let span = document.createElement('span');
span.innerText = this.names[key];
this.list.appendChild(span);
}
}
}
初始化的数据准备好了,在上述的代码中,我们通过 document.createElement()
这个原生的 API
创建了一个 span
标签,然后通过 appendChild()
方法将 span
标签插入到对应的元素中。这两个 DOM
的操作方法是我们最初学习 JS
时最早接触到的方法。
接下来我们就需要通过 JS
将每一个 span
标签的位置固定在圆的周围了,让我们一起来看相关的代码,如下:
class Lottery {
//...other code
draw() {
const spans = this.list.children;
for (let i = 0; i < spans.length; i++) {
let span = spans[i];
span.style.transform = `rotate(${i / this.names.length * 360 + this.deg}deg)`;
span.style.color = '#fff';
}
const now = ((360 - this.deg) / 360 * this.names.length | 0) % this.names.length;
this.list.setAttribute('data', this.names[now]);
spans[now].style.color = 'red';
if (this.run) {
this.slow = 1;
} else {
this.slow = this.slow * 0.995;
}
this.deg -= this.slow;
}
}
在上述代码中,我们通过循环前面生成的所有 span
标签,并给每个 span
标签都添加上相关的样式,最后实现的如下的静态画面:
到这里静态的圆已经通过 JS 动态绘制出来了,但是它还不会动,接下来我们就让它动起来。其实要让整个抽奖程序动起来也很简单,只需要添加一个定时器即可,代码如下:
class Lottery {
//...other code
animate() {
setInterval(() => this.draw(), 10);
}
}
我们只需要在 init
方法中调用 animate
即可。
到这里,还没完,剩下最后一步,就是何时让这个抽奖程序停下来呢?这里我给 document
添加了一个键盘抬起的事件,通过 addEventListener()
给 document
绑定了一个 keyup
事件,然后监听键盘的 code
是否为空格键,如果是空格键就停止,下面一起来看最后的代码:
class Lottery {
//...other code
event() {
document.addEventListener('keyup', (e) => {
if (e.code === 'Space') {
this.run = !this.run;
}
});
}
}
event
方法也需要在 init
方法中进行调用,这样当数据初始化好的时候就准备好了需要的内容。
最终的实现效果可以在这里进行查看:
总结
我们仅仅只使用了原生 JS 的几个 API ,就实现了这个抽奖效果。在实际的开发中,虽然我们已经很少用到这些原生的 API 了,但是我们还是需要知道相关的知识点,这样不仅对于我们的开发有帮助,对我们学习新的知识也会有帮助。让我们一起加油吧!
最后,如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,谢谢大家
往期回顾
转载自:https://juejin.cn/post/7152290793300951048