任務:
公司春節前辦聯歡會,有抽獎環節,抽獎共有若干輪,每次抽出幾人不等,抽中的人不參與後面的抽獎。
分析:
由於開發用自己的電腦,而在聯歡會現場要放在專門接投影儀的機器上,所以要跨平台性;參加聯歡會的員工可能經常要調整直到當天才能確認下來,所以還要方便對接員工來源資料,最後選擇了 JavaScript 這個純用戶端的語言,只要有IE就能運行,而且顯示效果可以完全交由CSS去支援,介面也可以做得很美觀。
環境:
IE 6+
思路:
把員工資料單獨存成文字檔,用 IE 的 Scripting.FileSystemObject 來讀取;
員工資料還要顯示三項,ID、人名和部門名稱,所以文字檔是從 Excel 中另存成跳格鍵分隔的資料,而用 JavaScript 列成表格輸出;
因為是投影顯示,所以全做成了按鍵盤控制的,捕捉按鍵事件用 document.onkeypress;
數組隨機排序,JavaScript 有非常方便的現成做法 array.sort(function(){return Math.random()>0.5?-1:1;});
代碼:
employ.txt
外部員工資料形如:
12009 姓名1 部門1
15971 姓名2 部門2
7815 姓名3 部門3
9483 姓名4 部門4
9507 姓名5 部門5
10589 姓名6 部門6
17212 姓名7 部門7
15487 姓名8 部門8
14934 姓名9 部門9
程式頁
lottery.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf8" /><title>隨機抽獎</title><style type="text/css"> body { overflow: hidden; background-image: url(bg.jpg); background-repeat: no-repeat; font-family: Arial, sans-serif; } h1 { margin-top: 130px; font-size: 40px; color: #FF0000; } #showlot { font-size: 30px; font-weight: bold; color: #FF0000; } #showlot td { width: 200px; } </style><script type="text/javascript"></script></head><body><h1 align="center">恭喜發財 好運全來</h1><div id="showlot"></div><script language="JavaScript" type="text/javascript"> //尋找數組裡是否有某元素 function inArray(arr,key) { re = new RegExp(key,[""]); return (arr.toString().replace(re,"┢").replace(/[^,┢]/g,"")).indexOf("┢"); } //JavaScritp 實現隨機抽獎小程式。從外部文字檔讀入到數組裡, //隨機排序數組後顯示在把用CSS去掉邊框的input格裡, // 用按鈕控制啟動和停止,每次迴圈顯示到數組結尾都會重新隨機排序從頭開始繼續迴圈。 //因為用 setInterval 控制函數,基本全用全域變數了 var fso, ts, str; var arrayUser = new Array(); //每次抽中的人數記到一個數組裡 var arrayBatch = new Array(10, 10, 10, 10, 10, 10, 10, 10,10, 10, 10, 10, 4, 2, 1, 1, 1, 1, 1, 1, 1); var indexBatch = 0; var ForReading = 1; //需要文字檔實體路徑,必須使用雙反斜線是因為 JavaScript 裡字串用/作逸出字元,必須用//表示/。 str = 'D://lucky//employ.txt'; fso = new ActiveXObject("Scripting.FileSystemObject"); ts = fso.OpenTextFile(str, ForReading); var i = 0; //把檔案內容逐行讀到數組裡 while (!ts.AtEndOfStream) { arrayUser[i++] = ts.ReadLine(); } // 關閉檔案 ts.Close(); //上來先亂序排一下 arrayUser.sort(function(){return Math.random()>0.5?-1:1;}); //timer是用來控制迴圈的指標變數。實際亂序的是數組元素,即每次迴圈數組都會重排一次從而值對應的鍵都會重排!而 time 始終是從0到數組長度。 timer = 0; str = ""; var arrayLine = new Array(); var arrayNow = new Array(); function lottery() { //剩下的數組元素個數不夠此批人數時就重頭再迴圈(這會讓每次最後剩下的幾個人機會稍微少一些),每次重新迴圈時都重新亂序排一下。需要用 >= 判斷 if (timer >= (arrayUser.length-arrayBatch[indexBatch]) ) { timer = 0; //讓 sort 的比較函數隨機傳回-1或1就可以了。如果其它排序方法可以使用其它的比較函數, // http: //webuc.net/dotey/archive/2004/12/06/2354.aspx 和 http://blog.iyi.cn/hily/archives/2005/09/javascript.html arrayUser.sort(function(){return Math.random()>0.5?-1:1;}); } else { str=""; arrayNow = new Array(); for (i = 0; i < arrayBatch[indexBatch]; i++) { arrayLine = arrayUser[timer].split("/t");//arrayUser[0][0]是員工號, arrayUser[0][1]是姓名,arrayUser[0][2]是部門 arrayNow[i] = arrayUser[timer]; //記下當前顯示的中獎人 str+="<tr><td>"+arrayLine[0]+"</td><td>"+arrayLine[1]+"</td><td>"+arrayLine[2]+"</td></tr>"; timer++; } str = '<table align="center">'+str+'</table>'; document.getElementById("showlot").innerHTML = str; } } //數字越大速度越慢 var speed=50; //把抽中的人記錄下來 var winIndex = 0; var arrayWin = new Array(); document.onkeypress=function() { //c 鍵是99,清空顯示;p 鍵是112,開始;s鍵是115,停止。 if (window.event.keyCode == 99) { //因為是各批人數多少不一,所以要清空現有批次顯示,以免前一批人多時後幾個人總顯示在後面的格裡 for (i = 0; i < 10; i++) { str= ""; document.getElementById("showlot").innerHTML =""; } } else if (window.event.keyCode == 112) { //因為是各批人數多少不一,所以要清空現有批次顯示,以免前一批人多時後幾個人總顯示在後面的格裡 for (i = 0; i < 10; i++) { str= ""; document.getElementById("showlot").innerHTML =""; } MyMar=setInterval(lottery, speed); } else if (window.event.keyCode == 115) { //先停止運行 clearInterval(MyMar); //把當前抽中的人記入到總體獲獎人數組中。 //其實可以簡化成每次停止時從全體使用者數組中刪除當前中獎的人, //但現在還記錄到總體獲獎人數組,是方便以後可以擴充成最後再顯示出所有中獎的人。 for (i = 0; i < arrayBatch[indexBatch]; i++) { arrayWin[winIndex] = arrayNow[i]; winIndex++; } // JavaScript 沒有現成的去掉數組元素的函數,由於每次都亂序排列數組,所以數組鍵是沒準的,所以乾脆自己用值判斷迴圈一下就把抽出的那人的值去掉了。 //迴圈一次,遇到抽中的人的值時就跳過,其餘的記錄下來。 var j = 0; var arrayNextpool = new Array(); for (i=0; i< arrayUser.length; i++) { //從總名單中去除已獲獎人 if (inArray(arrayWin, arrayUser[i]) >= 0) { continue; } else arrayNextpool[j++] = arrayUser[i]; } arrayUser = arrayNextpool; indexBatch++;//進到下一批次 timer = 0; //停止後就準備重新開始迴圈 } } </script></body></html>