欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【原】无脑操作:HTML5 + CSS + JavaScript实现比赛排程

程序员文章站 2022-03-29 19:21:47
1、背景:朋友请帮忙做一个比赛排程软件 2、需求: ① 比赛人数未知,可以通过文本文件读取参赛人员名称; ② 对参赛人员随机分组,一组两人,两两PK,如果是奇数人数,某一个参赛人员成为幸运儿自动晋级; ③ 比赛线下进行,比赛结束后,可以在线选择每组中晋级人员; ④ 晋级人员进行下一轮比赛分组,依此类 ......

1、背景:朋友请帮忙做一个比赛排程软件

2、需求:

① 比赛人数未知,可以通过文本文件读取参赛人员名称;

② 对参赛人员随机分组,一组两人,两两PK,如果是奇数人数,某一个参赛人员成为幸运儿自动晋级;

③ 比赛线下进行,比赛结束后,可以在线选择每组中晋级人员;

④ 晋级人员进行下一轮比赛分组,依此类推,直至最后一轮。

看完了以上的需求,聪明的你会做出什么样的分析和设计呢?以下是我的愚见。

3、分析:

① 考虑到该朋友的实际情况和业务需求,这个比赛排程软件显然越简单越傻瓜越好,所以在实现架构上不考虑BS架构,而考虑单页面呈现+参赛人员名称文本文档形式。

② 根据需求,大致绘制如下功能示意图,显然这样设计也是为了实现起来方便

【原】无脑操作:HTML5 + CSS + JavaScript实现比赛排程

4、实现:看到这里,聪明的你肯定有更好的实现方式啦!还请不低赐教哦!以下是我的实现写法

【原】无脑操作:HTML5 + CSS + JavaScript实现比赛排程
  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>汤胖专用_比赛排程器</title>
  9     <style>
 10         label {
 11             color: red;
 12         }
 13 
 14         div {
 15             display: inline;
 16             margin: 5px;
 17             padding: 2px;
 18         }
 19 
 20         .initDiv {
 21             background-color: black;
 22             color: white;
 23         }
 24 
 25         .matchDiv {
 26             background-color: orange;
 27             color: black;
 28         }
 29 
 30         .playerDiv {
 31             background-color: pink;
 32             color: black;
 33         }
 34 
 35         .resultDiv {
 36             background-color: green;
 37             color: white;
 38         }
 39 
 40         .resultData {
 41             background-color: blue;
 42             color: white;
 43         }
 44 
 45         .selectDiv {
 46             background-color: #666666;
 47             color: white;
 48         }
 49     </style>
 50 </head>
 51 
 52 <body>
 53     <fieldset>
 54         <legend>汤胖专用_比赛排程器の使用说明</legend>
 55         <ol>
 56             <li>选择的文件必须是utf-8格式</li>
 57             <li>使用Chrome浏览器或360浏览器的极速模式</li>
 58             <li>第一轮排程时,选择要使用的文本文件(参考模板文件)</li>
 59             <li>后续排程时,先点击刷新页面,再点击开始排程,即可使用上轮保存的过关人员</li>
 60         </ol>
 61     </fieldset>
 62     <hr/>
 63     <div>
 64         <input type="file" id="btnFiles" />
 65         <input type="button" id="btnPlan" value="步骤2、开始排程" />
 66         <input type="button" id="btnSave" value="步骤3、保存数据" />
 67         <input type="button" id="btnUpdate" value="步骤4、刷新页面" />
 68         <hr/>
 69     </div>
 70     <script>
 71         var arr = [];
 72         var resultData = [];
 73 
 74         // 扩展数组功能:实现随机排序
 75         if (!Array.prototype.shuffle) {
 76             Array.prototype.shuffle = function () {
 77                 for (var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] =
 78                     this[j], this[j] = x);
 79                 return this;
 80             };
 81         }
 82 
 83         // 扩展数组功能:实现删除指定值元素
 84         if (!Array.prototype.removeByValue) {
 85             Array.prototype.removeByValue = function (val) {
 86                 for (var i = 0; i < this.length; i++) {
 87                     if (this[i] == val) {
 88                         this.splice(i, 1);
 89                         break;
 90                     }
 91                 }
 92             };
 93         }
 94 
 95         // 页面初始化
 96         window.onload = function () {
 97             var btnFiles = document.getElementById('btnFiles');
 98             var btnPlan = document.getElementById('btnPlan');
 99             var btnSave = document.getElementById('btnSave');
100             var btnUpdate = document.getElementById('btnUpdate');
101 
102             btnFiles.onchange = importFile;
103             btnPlan.onclick = matchPlan;
104             btnSave.onclick = saveData;
105             btnUpdate.onclick = updatePage;
106         };
107 
108         // 以CSS类名获取元素
109         var getClass = function (classname) {
110             return document.getElementsByClassName(classname);
111         };
112 
113         var importFile = function () {
114             // 获取读取的File对象
115             var selectedFile = document.getElementById("btnFiles").files[0];
116             if (selectedFile.name) {
117                 // 读取选中文件的文件名
118                 var name = selectedFile.name;
119                 // 读取选中文件的大小
120                 var size = selectedFile.size;
121 
122                 // 读取操作
123                 var reader = new FileReader();
124                 // 读取文件的内容
125                 reader.readAsText(selectedFile);
126 
127                 reader.onload = function () {
128                     // 当读取完成之后会回调这个函数,然后文件内容存储到result
129                     var temparr = this.result.split(/[\s\n]/);
130                     temparr.forEach(function (v, i) {
131                         if (v != '') {
132                             arr.push(v);
133                         }
134                     });
135 
136                     // 第一轮排程时,文本文件内容存储在sessionStorage中,后续均使用sessionStorage
137                     sessionStorage.setItem('resultData', arr);
138                 };
139             }
140         };
141 
142         var matchPlan = function () {
143             if (sessionStorage.getItem('resultData')) {
144                 arr = sessionStorage.getItem('resultData').split(',');
145             }
146 
147             var initLabel = document.createElement('label');
148             initLabel.className = 'initLabel';
149             initLabel.innerText = '初始数据:';
150             document.body.appendChild(initLabel);
151 
152             for (var i = 0; i < arr.length; i++) {
153                 var tempdiv = document.createElement('div');
154                 tempdiv.id = 'initDiv' + i;
155                 tempdiv.className = 'initDiv';
156                 tempdiv.innerText = arr[i];
157                 document.body.appendChild(tempdiv);
158             }
159 
160             // 随机排序
161             arr.shuffle();
162 
163             // 换行
164             document.body.appendChild(document.createElement('br'));
165             document.body.appendChild(document.createElement('br'));
166 
167             // 显示参赛人员数据
168             var matchLabel = document.createElement('label');
169             matchLabel.innerText = '随机排序:';
170             document.body.appendChild(matchLabel);
171 
172             for (var i = 0; i < arr.length; i++) {
173                 var tempdiv = document.createElement('div');
174                 tempdiv.id = 'matchDiv' + i;
175                 tempdiv.className = 'matchDiv';
176                 tempdiv.innerText = arr[i];
177                 document.body.appendChild(tempdiv);
178             }
179 
180             document.body.appendChild(document.createElement('hr'));
181 
182             var temp = document.createElement('label');
183             temp.className = 'initLabel';
184             temp.innerText = '比赛分组:';
185             document.body.appendChild(temp);
186 
187             // 换行
188             document.body.appendChild(document.createElement('br'));
189             document.body.appendChild(document.createElement('br'));
190 
191             for (var i = 0; i < arr.length; i++) {
192                 if (i % 2 == 0) {
193                     var groupLabel = document.createElement('label');
194                     groupLabel.innerText = "第" + (Math.round(i / 2) + 1) + "组:";
195                     document.body.appendChild(groupLabel);
196 
197                     var player1div = document.createElement('div');
198                     player1div.id = 'playerDiv' + i;
199                     player1div.className = 'playerDiv';
200                     player1div.innerText = arr[i];
201                     document.body.appendChild(player1div);
202                 } else {
203                     var groupLabel = document.createElement('label');
204                     groupLabel.className = 'initLabel';
205                     groupLabel.innerText = " VS ";
206                     document.body.appendChild(groupLabel);
207 
208                     var player2div = document.createElement('div');
209                     player2div.id = 'playerDiv' + i;
210                     player2div.className = 'playerDiv';
211                     player2div.innerText = arr[i];
212                     document.body.appendChild(player2div);
213 
214                     // 换行
215                     document.body.appendChild(document.createElement('br'));
216                     document.body.appendChild(document.createElement('br'));
217                 }
218             }
219 
220             document.body.appendChild(document.createElement('hr'));
221 
222             var resultLabel = document.createElement('label');
223             resultLabel.innerText = "过关人员:";
224             document.body.appendChild(resultLabel);
225 
226             // 换行
227             document.body.appendChild(document.createElement('br'));
228             document.body.appendChild(document.createElement('br'));
229 
230             for (var i = 0; i < getClass('playerDiv').length; i++) {
231                 // 获取比赛分组div元素并绑定双击事件
232                 getClass('playerDiv')[i].ondblclick = function () {
233                     // 设置比赛分组div元素双击后不能再被双击
234                     this.style['pointer-events'] = 'none';
235                     this.setAttribute("class", "selectDiv");
236 
237                     var tempdiv = document.createElement('div');
238                     tempdiv.id = 'resultDiv' + i;
239                     tempdiv.className = 'resultDiv';
240                     tempdiv.innerText = this.innerText;
241                     document.body.appendChild(tempdiv);
242 
243                     resultData.push(this.innerText);
244 
245                     for (var i = 0; i < getClass('resultDiv').length; i++) {
246                         getClass('resultDiv')[i].ondblclick = function () {
247                             document.body.removeChild(this);
248                             resultData.removeByValue(this.innerText);
249 
250                             for (var i = 0; i < getClass('selectDiv').length; i++) {
251                                 if (this.innerText == getClass('selectDiv')[i].innerText) {
252                                     // 设置比赛分组div元素可以被双击
253                                     getClass('selectDiv')[i].style['pointer-events'] = 'auto';
254                                     getClass('selectDiv')[i].setAttribute("class", "playerDiv");
255                                 }
256                             }
257                         };
258                     }
259                 };
260             }
261         };
262 
263         // 保存数据供下一轮排程使用
264         var saveData = function () {
265             // 使用HTML5的SessionStorage在当次会话期间在客户端浏览器中存储数据
266             sessionStorage.setItem('resultData', resultData);
267         };
268 
269         // 刷新页面,开始下一轮排程
270         var updatePage = function () {
271             window.location.reload();
272         };
273     </script>
274 </body>
275 
276 </html>
实现代码