原生javascript实现老.虎机抽奖点名demo源码思路解析
想着使用原生Javascript做一个随机点名的小应用,
也可以做抽奖使用。
html简单化,人名单可以通过js生成并处理。
可以非常随意的添加修改人名字。
应用想带点特效,比如老.虎机转动的特效。
思路入下:
借鉴模板引擎的思想,在页面中添加一个指定ID的script标签,我们可以在任意文本中将提前准备好的人名单复制进来并添加注释。
利用正则处理空白字符,把所有人名添加到数组当中,再删除该script节点,在这里我们只讨论名字为两个字或者三个字的。
遍历数组,此时数组的每一项是一个人名,有两个字的和三个字的。
对数组的每一项进行split操作,使得每一个名字变成一个数组。
接下来处理长度只有2(名字是两个字)的数组,把数组【0】个之后添加一个空字符串,使得所有的姓名数组长度都为3。
点击按钮,开始按钮文字更改‘停止,先执行函数randomName随机出一个姓名【‘1’,‘2’,‘3’】放在对应的三个展示框中。
展示框同时开始滚动,展示框的高度为300px。
开启定时器,在定时器内进行检测,当前的top值余300如果等于-290,说明再往上滚动10当前最后一个姓名就展示完了。
此时需要继续在后面借着生成姓名追加到三个展示框内,所以此时应该执行randomName函数。
当点击停止口,停止按钮的文字变成请稍后,此时需要做一个老.虎机结束,滚动减慢最后确定一个姓名的函数。
清楚上一个定时器,重新开始一个定时器。
定义一个变量,确定此时老.虎机慢速度转几个停下。
k = i - 900 - (300 + i % 300);
i%300 计算的是 当前正在滚动出去的这个姓名还差多少px完整滚动出去。
300 + i % 300 计算的是当前正在滚动进来的姓名还差多少px完整显示出来。
900 是一个可更改的值,值为300的倍数,在这里赋值计算的是点击停止后再 滚动900/300个姓名停下。
i - 900 - (300 + i % 300)计算的就是点击停止后,需要再滚动多少px。
再新的慢速定时器中继续执行randomName函数,继续生成姓名并追加。
判断,当top值等于k时,清除定时器,为了保证准确性,需要最后再次赋值top值等于 k 或 i。
因为在定时器中i -= 5,可能会产生微小误差。
下面上源码:
0 | <!DOCTYPE html> |
1 | <html lang="en"> |
2 | |
3 | <head> |
4 | <meta charset="UTF-8"> |
5 | <title>点名系统v1.1</title> |
6 | <style> |
7 | * { |
8 | margin: 0; |
9 | padding: 0; |
10 | } |
11 | |
12 | body { |
13 | background-color: #000; |
14 | overflow: hidden; |
15 | } |
16 | |
17 | ul { |
18 | list-style: none; |
19 | } |
20 | input{ |
21 | outline-style: none; |
22 | } |
23 | .max { |
24 | width: 1000px; |
25 | height: 300px; |
26 | font-size: 30px; |
27 | font-weight: 0; |
28 | cursor: pointer; |
29 | margin: 50px auto 0; |
30 | border-top: 1px solid green; |
31 | border-bottom: 1px solid green; |
32 | box-sizing: border-box; |
33 | position: relative; |
34 | transition: all 0.5s; |
35 | } |
36 | |
37 | .max:hover { |
38 | font-size: 40px; |
39 | font-weight: bold; |
40 | } |
41 | |
42 | #box, |
43 | #box1, |
44 | #box2 { |
45 | width: 300px; |
46 | height: 300px; |
47 | font-family: "微软雅黑"; |
48 | line-height: 300px; |
49 | text-align: center; |
50 | overflow: hidden; |
51 | position: absolute; |
52 | top: -1px; |
53 | } |
54 | |
55 | #box li, |
56 | #box1 li, |
57 | #box2 li { |
58 | width: 300px; |
59 | height: 300px; |
60 | box-sizing: border-box; |
61 | color: #fff; |
62 | font-family: "微软雅黑"; |
63 | line-height: 300px; |
64 | text-align: center; |
65 | overflow: hidden; |
66 | float: left; |
67 | background-color: rgba(0, 0, 0, 0); |
68 | border: 1px solid green; |
69 | box-sizing: border-box; |
70 | margin: 0; |
71 | } |
72 | |
73 | #box { |
74 | left: 0; |
75 | } |
76 | |
77 | #box1 { |
78 | left: 350px; |
79 | } |
80 | |
81 | #box2 { |
82 | right: 0; |
83 | } |
84 | |
85 | #box ul, |
86 | #box1 ul, |
87 | #box2 ul { |
88 | position: absolute; |
89 | left: 0; |
90 | top: 0; |
91 | } |
92 | |
93 | #btn { |
94 | width: 200px; |
95 | height: 60px; |
96 | display: block; |
97 | text-decoration: none; |
98 | border: 1px solid #eee; |
99 | border-radius: 30px; |
100 | line-height: 60px; |
101 | text-align: center; |
102 | color: #eee; |
103 | font-family: "微软雅黑"; |
104 | font-size: 18px; |
105 | margin: 0 auto 100px; |
106 | transition: all 1s; |
107 | } |
108 | |
109 | #btn:hover { |
110 | width: 1000px; |
111 | border-color: green; |
112 | color: green; |
113 | } |
114 | |
115 | p { |
116 | color: green; |
117 | font-size: 12px; |
118 | text-align: center; |
119 | line-height: 16px; |
120 | } |
121 | |
122 | #sp { |
123 | display: block; |
124 | width: 1000px; |
125 | height: 100px; |
126 | font-size: 6px; |
127 | font-family: "微软雅黑"; |
128 | margin: 0 auto; |
129 | line-height: 100px; |
130 | text-align: center; |
131 | color: green; |
132 | animation: myfirst 0.5s paused forwards; |
133 | } |
134 | |
135 | @keyframes myfirst { |
136 | from { |
137 | bfont-size: 16px; |
138 | } |
139 | to { |
140 | font-size: 30px; |
141 | } |
142 | } |
143 | </style> |
144 | </head> |
145 | <body> |
146 | <div class="max"> |
147 | <div id="box"> |
148 | <ul> |
149 | <li>攻城狮,</li> |
150 | </ul> |
151 | </div> |
152 | <div id="box1"> |
153 | <ul> |
154 | <li>ready?</li> |
155 | </ul> |
156 | </div> |
157 | <div id="box2"> |
158 | <ul> |
159 | <li>go!</li> |
160 | </ul> |
161 | </div> |
162 | </div> |
163 | <span id="sp"></span> |
164 | <a href="javascript:void(0)" id="btn">开始</a> |
165 | <p>说明:将任意名单复制粘贴到页面id为names的标签内添加注释,即可开始随机点名!</p> |
166 | <p style="color:#000">作者:陈晨</p> |
167 | </body> |
168 | <script id="names"> |
169 | /* |
170 | 张孝梅 陈惠芳 翟英祥 催渊 涂新昭 罗平益 谢韶光 杨凯 李佳佳 刘轲轲 杨红哲 张荣秋 王小策 费伊蒙 杜程 李杰 周曼 孔德晨 池远哲 李娜 张雪 张钧 杜东阳 刘冲冲 刘硕 袁冬 孙守鑫 殷昊 孙红厚 高全 |
171 | */ |
172 | </script> |
173 | <script> |
174 | var sp = document.getElementById('sp'), |
175 | box = document.getElementById('box'), |
176 | box1 = document.getElementById('box1'), |
177 | box2 = document.getElementById('box2'), |
178 | ul = box.getElementsByTagName('ul')[0], |
179 | ul1 = box1.getElementsByTagName('ul')[0], |
180 | ul2 = box2.getElementsByTagName('ul')[0], |
181 | lis = ul.getElementsByTagName('li'), |
182 | lis1 = ul1.getElementsByTagName('li'), |
183 | lis2 = ul2.getElementsByTagName('li'), |
184 | btn = document.getElementById('btn'), |
185 | names = document.getElementById('names').innerHTML, |
186 | Rnam1 = /^\s{0,}\/\*\s{0,}|\s{0,}\*\/\s{0,}$/g, |
187 | Rnam2 = /\s{1,}/g, |
188 | names = names.replace(Rnam1, ""), |
189 | names = names.replace(Rnam2, ","), |
190 | nameArr = names.split(","), |
191 | timer = null, |
192 | timerFalse = null, |
193 | flag = true, |
194 | i = 0, |
195 | randoma,li, li1, li2,k,one,two,three; |
196 | console.log(nameArr); |
197 | document.getElementById('names').parentNode.removeChild(document.getElementById('names')); |
198 | for (var j = 0; j < nameArr.length; j++) { |
199 | nameArr[j] = nameArr[j].split(''); |
200 | if (nameArr[j].length != 3) { |
201 | nameArr[j].splice(1, 0, '_'); |
202 | } |
203 | } |
204 | btn.addEventListener('click', function() { |
205 | if (flag == true && btn.innerHTML == '开始') { |
206 | flag = false; |
207 | btn.innerHTML = '停止'; |
208 | sp.innerHTML = ''; |
209 | sp.style.animation = 'none'; |
210 | randomName(); |
211 | timer = setInterval(play, 5); |
212 | |
213 | function play() { |
214 | if (i % 300 == -290) { |
215 | randomName(); |
216 | } |
217 | ul.style.top = i + 'px'; |
218 | ul1.style.top = i + 'px'; |
219 | ul2.style.top = i + 'px'; |
220 | i -= 5; |
221 | } |
222 | } else { |
223 | clearInterval(timer); |
224 | if (btn.innerHTML == '停止') { |
225 | btn.innerHTML = '请稍后……'; |
226 | timerFalse = setInterval(stop, 30); |
227 | } |
228 | k = i - 900 - (300 + (i % 300)); |
229 | |
230 | function stop() { |
231 | if (i != k) { |
232 | if (i % 300 == -290) { |
233 | randomName(); |
234 | } |
235 | ul.style.top = i + 'px'; |
236 | ul1.style.top = i + 'px'; |
237 | ul2.style.top = i + 'px'; |
238 | i -= 5; |
239 | } else { |
240 | ul.style.top = i + 'px'; |
241 | ul1.style.top = i + 'px'; |
242 | ul2.style.top = i + 'px'; |
243 | btn.innerHTML = '开始'; |
244 | flag = true; |
245 | clearInterval(timerFalse); |
246 | var two = lis1[Math.abs(i / 300)].innerHTML; |
247 | if (two == "_") { |
248 | two = ''; |
249 | } |
250 | sp.innerHTML = '让我们有请<span style="color:red;">' + lis[Math.abs(i / 300)].innerHTML + two + lis2[Math.abs(i / 300)].innerHTML + '</span>同学发表个人意见'; |
251 | one = lis[Math.abs(i / 300)].cloneNode(true); |
252 | two = lis1[Math.abs(i / 300)].cloneNode(true); |
253 | three = lis2[Math.abs(i / 300)].cloneNode(true); |
254 | ul.innerHTML = ul1.innerHTML = ul2.innerHTML = ''; |
255 | ul.style.top = ul1.style.top = ul2.style.top = '0'; |
256 | i = 0; |
257 | ul.appendChild(one); |
258 | ul1.appendChild(two); |
259 | ul2.appendChild(three); |
260 | sp.style.animation = 'myfirst 0.5s running forwards'; |
261 | } |
262 | } |
263 | } |
264 | }) |
265 | |
266 | function randomName() { |
267 | li = document.createElement('li'); |
268 | li1 = document.createElement('li'); |
269 | li2 = document.createElement('li'); |
270 | randoma = parseInt(Math.random() * nameArr.length); |
271 | li.innerHTML = nameArr[randoma][0]; |
272 | li1.innerHTML = nameArr[randoma][1]; |
273 | li2.innerHTML = nameArr[randoma][2]; |
274 | ul.appendChild(li); |
275 | ul1.appendChild(li1); |
276 | ul2.appendChild(li2); |
277 | } |
278 | </script> |
279 | |
280 | </html> |
281 |
结合源码再看一遍我的思路,相信大家就很清楚了,如果还有不清楚的或者有更好的意见,欢迎留言讨论。