点名系统实现
演示: http://lu-renjiajia.gitee.io/random-roll-call
1.靜態(tài)頁(yè)面部分
主要采用css的彈性布局flex;
html代碼如下:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" /><meta name="viewport"content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" /><title>?????辛?????</title><link href="./favicon(2).ico" rel="shortcut icon" type="image/x-icon" /><link rel="stylesheet" href="./css/index.css"><script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> </head> <body><h1>被選中的小伙伴們:</h1><div class="ll"><select class="lxx" name="" id="aselect"><option value="5">5秒</option><option value="10">10秒</option><option value="15">15秒</option><option value="20">20秒</option></select><button class="lxx">開(kāi)始</button><input class="lxx" type="text" id="personNum" value="1"></div><ul></ul><audio id="aut" src="./audio/自定義語(yǔ)言包.mp3" style="width: 0;"></audio> </body> <script src="./js/index.js"></script> </html>css代碼:
* {margin: 0;padding: 0;box-sizing: border-box;}body {padding: 20px 0px;background: url(../img/11.webp);background-size: cover;background-position: center top;background-repeat: no-repeat;}@media screen and (max-width:750px){body {background: url(../img/bg.webp);/* background-size: 100%; */background-size:cover;background-position: center top;background-repeat: no-repeat;}}h1 {padding: 10px;background-color: #327dcd;color: purple;/* margin: 10px 0; */transition: all 1s;text-align: center;}ul {list-style: none;display: flex;flex-wrap: wrap;justify-content: space-around;overflow: hidden;}li {width: 100px;height: 40px;background-color: rgb(71, 134, 222);color: #fff;display: flex;align-items: center;justify-content: center;margin: 10px;}/* 確定下來(lái)了 最終被選中 */.select {background-color: palevioletred;color: #fff;}.lxx{width: 100px;height: 50px;color: #fff;border: none;font-size: 20px;background: rgb(14, 149, 161);box-shadow: 40px 40px 80px rgb(71, 134, 222),-40px -40px 80px rgb(71, 134, 222);text-align: center;cursor: pointer;}.lxx:hover{background-color: rgb(11, 82, 181);}.ll{display: flex;justify-content: space-around;align-items: center;margin-top: 20px;}#personNum{height: 30px;}#aselect{height: 30px;}2.功能實(shí)現(xiàn)
功能1:渲染名單到頁(yè)面;
思路:即已拿到了字符串名稱(chēng);
可以通過(guò)字符串的split()方法來(lái)通過(guò)特定的字符來(lái)把字符串轉(zhuǎn)換為數(shù)組;
代碼如下:
const str = '張國(guó)穎 邱成武 謝曉華 廖浩然 竇廣燦 陳澤鋒 藍(lán)湘杰 陳錦田 陳天培 王德懷 吳柏奇 李遠(yuǎn)寧 顏石偉 梁品鑫 范名杰 劉婷 梁海齡 戴嘉琪 張雄杰 潘科華 馬漢文 鄧嘉豪 周康凱 劉森琪 張陽(yáng) 徐君豪 黃俊博 張家鳳 周日禧 黃善橋 藍(lán)梓豪 勞政永 林泓森 秦柏林 薛巖 張旭東 鐘世添 嚴(yán)文聰 余家凱 莫志俊 白麗臣 邱宗煥 梁碧燕 陳秋歌 黃光衡 侯正銘 劉辛 劉新勇 廖錦龍 謝文堅(jiān) 曾子杭 滕飛 姚鑫濤 林蔚坤 彭奕安 廖有金 劉皓天 陳凱麟 陳巧 榮棒 莫格云 黃偉龍 闕娟 蘇彩 陳星 金金亮 黎梓燁 劉松 丘翠嫻 彭玉馨 肖根欽 陳冠錦 劉慶邦 曾海龍 謝偉平 劉文輝 于延杰';接下來(lái)把拿到的數(shù)組進(jìn)行頁(yè)面渲染;通過(guò)反引號(hào)${}來(lái)獲取值,在通過(guò)innerHTML來(lái)添加進(jìn)入我們要的標(biāo)簽當(dāng)中
let xuanRan = () => {let liHTML = "";for (let i = 0; i < arr.length; i++) {liHTML += `<li>${arr[i]}</li>`}ul.innerHTML = liHTML; }功能2:需要一個(gè)隨機(jī)函數(shù),
通過(guò)Math對(duì)象里面的Math.random()方法!!!
let getRandom=(max, min)=>{return Math.floor(Math.random() * (max - min + 1) + min); }功能3:隨機(jī)抽取幸運(yùn)觀眾
思路,先從整個(gè)數(shù)組中,抽取我定義的人的個(gè)數(shù),把這些人存入一個(gè)數(shù)組,并返回,slice(x)可以從x下標(biāo)開(kāi)始,截取從該下標(biāo)開(kāi)始的到數(shù)組末尾的整個(gè)數(shù)組,并返回;
let myRandomArr = (arrList, num) => {if (num > arrList.length) {return;} else {let tempArr = arrList.slice(0);let newArrList = [];for (let i = 0; i < num; i++) {let random = getRandom(tempArr.length - 1, 0);let arr = tempArr[random];tempArr.splice(random, 1);newArrList.push(arr);}return newArrList;} }值得一提的是,我需要改變?cè)瓟?shù)組的內(nèi)容,保證我頁(yè)面已經(jīng)渲染到的,被選出來(lái)的元素,不在被選中,我這采用了過(guò)濾操作,返回被選中的數(shù)組之外的元素,并重新賦值給原數(shù)組
for (let j = 0; j < choice.length; j++) {arr = arr.filter(item => item != choice[j]);}功能4:把我抽取的數(shù)組進(jìn)行樣式的添加和渲染到結(jié)果和標(biāo)簽中
思路:通過(guò)對(duì)整個(gè)數(shù)組的
for (let j = 0; j < choice.length; j++) {if (lis[i].innerText === choice[j]) {lis[i].classList.add("select");}}遍歷,先通過(guò)排他思想把所有的li的select類(lèi)清除掉
其次我還有保留我上次選中的li的select不被清楚
思路:通過(guò)頁(yè)面中span標(biāo)簽里面的innerTetx來(lái)與li中每一個(gè)進(jìn)行對(duì)比,如果存在,那么在全部清除樣式后在把這個(gè)加上
for (let j = 0; j < spans.length; j++) {if (spans[j].innerText === lis[i].innerText) {lis[i].classList.add("select");}}說(shuō)明:另一種思路,就是在排他時(shí)是就進(jìn)行判定,如果存在,則不刪這個(gè),使用continue跳出本次循環(huán);(這里就不寫(xiě)代碼了);
功能5:為了保證我們能個(gè)一直產(chǎn)生隨機(jī)數(shù),一直隨機(jī)抽取,我們需要一個(gè)定時(shí)器
思路,把功能四放進(jìn)一個(gè)定時(shí)器里面,時(shí)間參數(shù),為我們?cè)谧远x的時(shí)間(隨機(jī)抽取的速度)。即可
timer = setInterval(() => {//功能4 ,時(shí)間}功能6:我們需要設(shè)置隨機(jī)抽取的結(jié)束時(shí)間
思路:設(shè)置一個(gè)延時(shí)器,結(jié)束時(shí)間為我們?cè)谕饷娅@取的自定義設(shè)置的時(shí)間;然后再延時(shí)器里面清除定時(shí)器;然后重新渲染我們選中人后添加了select樣式的頁(yè)面;
setTimeout(() => {clearInterval(timer);xuanRanPerson();}, time1 * 1000)功能7:渲染我們抽中的人,加上select類(lèi)后的樣式頁(yè)面
思路:通過(guò)insertAdjacentHTML()來(lái)進(jìn)行添加,beforeend表示在子元素的末尾加,反引號(hào)``添加標(biāo)簽
let xuanRanPerson = () => {for (let i = 0; i < choice.length; i++) {h1.insertAdjacentHTML("beforeend",`<span>${choice[i]}</span>`)}}功能8:修改h1文字的顏色,隨機(jī)變色
思路:通過(guò)rgb的三個(gè)值0-255,可以用隨機(jī)數(shù)范圍在0-255,隨機(jī)生成三個(gè)數(shù)給三個(gè)參數(shù),q,w,e;通過(guò)style去修改
let q, w, e; setInterval(() => {q = getRandom(255, 0);w = getRandom(255, 0);e = getRandom(255, 0);h1.style.color = `rgb(${q},${w},${e})` }, 1000)功能9:谷歌瀏覽器的語(yǔ)音播報(bào)
思路:通過(guò)SpeechSynthesisUtterance對(duì)象來(lái)操作,為了保證每次讀的不會(huì)重復(fù)上次抽取到的人,每次播報(bào)完后進(jìn)行置空,加“,”使瀏覽器閱讀一個(gè)名字后,會(huì)暫停一秒;
let bobao = () => {let text = namearr.join(",");let msg = new SpeechSynthesisUtterance(text);msg.rate = 0.3;msg.pitch = 1;msg.volume = 1;speechSynthesis.speak(msg);text = "";namearr = []; }功能10:開(kāi)始按鈕的語(yǔ)音播報(bào)
思路:自己找al語(yǔ)音助手生成的語(yǔ)音,并錄制下來(lái),然后轉(zhuǎn)為MP4格式,在利用audio的方法play(),pause()來(lái)進(jìn)行控制
let audioPlay = () => {let aut = document.querySelector("#aut");if (aut !== null) {if (aut.paused) {aut.play();} else {aut.pause();}} }優(yōu)化1:為了保證我點(diǎn)擊按鈕后不會(huì)觸發(fā)第二定時(shí)器,使頁(yè)面混亂;
思路:1.我在開(kāi)啟定時(shí)器之前,關(guān)閉定時(shí)器;
2:直接點(diǎn)擊按鈕后,把按鈕禁用,只有延時(shí)器開(kāi)始后,關(guān)閉定時(shí)器的時(shí)候,在把按鈕啟用;
優(yōu)化2:對(duì)于自定義的人數(shù),規(guī)定1-20人
源碼:
js:
const str = '張國(guó)穎 邱成武 謝曉華 廖浩然 竇廣燦 陳澤鋒 藍(lán)湘杰 陳錦田 陳天培 王德懷 吳柏奇 李遠(yuǎn)寧 顏石偉 梁品鑫 范名杰 劉婷 梁海齡 戴嘉琪 張雄杰 潘科華 馬漢文 鄧嘉豪 周康凱 劉森琪 張陽(yáng) 徐君豪 黃俊博 張家鳳 周日禧 黃善橋 藍(lán)梓豪 勞政永 林泓森 秦柏林 薛巖 張旭東 鐘世添 嚴(yán)文聰 余家凱 莫志俊 白麗臣 邱宗煥 梁碧燕 陳秋歌 黃光衡 侯正銘 劉辛 劉新勇 廖錦龍 謝文堅(jiān) 曾子杭 滕飛 姚鑫濤 林蔚坤 彭奕安 廖有金 劉皓天 陳凱麟 陳巧 榮棒 莫格云 黃偉龍 闕娟 蘇彩 陳星 金金亮 黎梓燁 劉松 丘翠嫻 彭玉馨 肖根欽 陳冠錦 劉慶邦 曾海龍 謝偉平 劉文輝 于延杰'; let arr = str.split(" "); let ul = document.querySelector("ul"); let btn = document.querySelector("button"); let timer; let time1;let xiaoid; let namearr = []; let choice=[]; let data = []; let h1 = document.querySelector("h1"); let personNum = document.querySelector("#personNum"); //渲染頁(yè)面 let xuanRan = () => {let liHTML = "";for (let i = 0; i < arr.length; i++) {liHTML += `<li>${arr[i]}</li>`}ul.innerHTML = liHTML; } //調(diào)用 xuanRan(); //添加點(diǎn)擊事件 btn.addEventListener("click", (e) => {//清除定時(shí)器,延時(shí)器clearInterval(timer);clearTimeout(xiaoid)let lis = document.querySelectorAll("li");let aselect = document.querySelector("#aselect");let pernum = parseInt(personNum.value);let spans = document.querySelectorAll("span") || null;time1 = parseInt(aselect.value);//語(yǔ)音提示播報(bào)if (pernum > arr.length) {let str='您好,數(shù)據(jù)過(guò)大,查詢(xún)?nèi)藬?shù)不得大于候選的人數(shù)';alert('您好,數(shù)據(jù)過(guò)大,查詢(xún)?nèi)藬?shù)不得大于候選的人數(shù)')bobao(str);btn.disabled = false;return;}else if(pernum===0){let str='您好,要查詢(xún)的人數(shù)不能為0';alert('您好,要查詢(xún)的人數(shù)不能為0');bobao(str);btn.disabled = false;return;}else if (pernum > 20) {let str='您好,不能一次性查找20人以上';alert('您好,不能一次性查找20人以上');bobao(str);btn.disabled = false;return;} else {//調(diào)用開(kāi)始的音頻audioPlay();timer = setInterval(() => {//從候選名單內(nèi)獲取長(zhǎng)度為pernum的不重復(fù)數(shù)組choice = myRandomArr(arr, pernum);//先把所有的li的樣式去掉for (let i = 0; i < lis.length; i++) {lis[i].classList.remove("select");for (let j = 0; j < spans.length; j++) {//已選中的,且渲染在span標(biāo)簽里面的樣式加回來(lái)if (spans[j].innerText === lis[i].innerText) {lis[i].classList.add("select");}}//被選中的人加上樣式for (let j = 0; j < choice.length; j++) {if (lis[i].innerText === choice[j]) {lis[i].classList.add("select");}}}}, 50);//延時(shí)器,延時(shí)time1*1000 秒后清除定時(shí)器 time1為我頁(yè)面設(shè)置時(shí)間xiaoid=setTimeout(() => {//用于語(yǔ)音播報(bào)的數(shù)組添加我選中的人for (let i = 0; i < choice.length; i++) {namearr.push(choice[i]);}//創(chuàng)參數(shù)調(diào)用播報(bào)函數(shù)bobao(namearr);//防止我選中的人在此被選中,把我選中的數(shù)組外的人從新賦值給原數(shù)組for (let j = 0; j < choice.length; j++) {arr = arr.filter(item => item != choice[j]);}btn.disabled = false;clearInterval(timer);//渲染被選中,加上樣式的人xuanRanPerson();}, time1 * 1000)} }); //渲染被選中,加上樣式的人 let xuanRanPerson = () => {for (let i = 0; i < choice.length; i++) {h1.insertAdjacentHTML("beforeend",`<span>${choice[i]}</span>`)} } //獲取隨機(jī)數(shù) let getRandom=(max, min)=> {return Math.floor(Math.random() * (max - min + 1) + min); } //生成rgb的三個(gè)參數(shù) let q, w, e; setInterval(() => {q = getRandom(255, 0);w = getRandom(255, 0);e = getRandom(255, 0);h1.style.color = `rgb(${q},${w},${e})` }, 1000) //隨機(jī)抽取不重復(fù)的數(shù)組 let myRandomArr = (arrList, num) => {if (num > arrList.length) {return;} else {let tempArr = arrList.slice(0);let newArrList = [];for (let i = 0; i < num; i++) {let random = getRandom(tempArr.length - 1, 0);let arr = tempArr[random];tempArr.splice(random, 1);newArrList.push(arr);}return newArrList;} } //音頻的開(kāi)關(guān) let audioPlay = () => {let aut = document.querySelector("#aut");if (aut !== null) {if (aut.paused) {aut.play();} else {aut.pause();}} } //語(yǔ)音播報(bào) let bobao = (a) => {let text;if(a instanceof Array){text = a.join(",");}else if(1||str){text=a;}let msg = new SpeechSynthesisUtterance(text);console.log(text);msg.rate = 0.6;msg.pitch = 1;msg.volume = 1;speechSynthesis.speak(msg);text = "";namearr = []; }總結(jié)
- 上一篇: Java计算任意多边形面积
- 下一篇: Databricks 第5篇:Datab