zoukankan      html  css  js  c++  java
  • 【原】无脑操作:HTML5 + CSS + JavaScript实现比赛排程

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

    2、需求:

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

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

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

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

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

    3、分析:

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

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

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

      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
    ]/);
    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>
    实现代码
  • 相关阅读:
    javaweb消息中间件——rabbitmq入门
    virtual box 桥接模式(bridge adapter)下无法获取ip(determine ip failed)的解决方法
    Apache Kylin本地启动
    git操作
    Java学习总结
    Java中同步的几种实现方式
    hibernate exception nested transactions not supported 解决方法
    vue 中解决移动端使用 js sdk 在ios 上一直报invalid signature 的问题解决
    cookie 的使用
    vue 专门为了解决修改微信标题而生的项目
  • 原文地址:https://www.cnblogs.com/iflytek/p/9442084.html
Copyright © 2011-2022 走看看