對不起,在下小的我要用小戴女神撐過 2 天了QQ
小戴對不起(#
昨天初步用 JavaScript 控制了網頁元素,
今天要來更進階的 addEventListener 事件監聽,
這就是像如果滑鼠 hover 過去或點下元件要做什麼事。
昨天只有列出世界女單前 25 名與小戴現在分數差距,
如果我想要知道世界女單前 25 名各國選手各有幾個要怎麼辦呢?
這邊我們先在 html 寫出下拉式選單:
<select name="" id="optionSelected">
<option value="1">1. 世界女單前 25 名與小戴現在分數差距</option>
<option value="2">2. 世界女單前 25 名人數 (by國家)</option>
</select>
然後我們為下拉式選單增加 addEventListener,
我們的最終目標是根據點擊的下拉式選單的選項(值)下面要顯示不同內容。
一開始我們先監聽這個元件的點擊事件,
所以我們就可以在 JavaScript 寫:
const optionElement = document.getElementById("optionSelected");
optionElement.addEventListener("click",contentShow); // 當下拉式選單被點擊時,要執行什麼函數
function countryShow(){
console.log("有被點擊到");
}
看來有做出我們想要的樣子~~~
JavaScript 中有一個可以取得觸發事件當下物件的值 event.target.value,
有興趣的可以 console.log(event) 出來看看,裡面有很多東西可以研究XD
本日就先暫時不介紹。
function contentShow(event){
console.log("有被點擊到");
console.log(`所點擊的值為: ${event.target.value}`);
}
除了事件監聽,
本日還有一個大難題要解決,
我們要怎麼從 25 個女單選手中 distinct 出 國家與人數對照呢?
這邊我之前有試過要自己寫,寫不出來,
於是只好網路搜尋大大的解法了,下面有稍微註解一下。
不過這邊稍微講一下,
大概做法是將國家存成陣列的 index 值,
然後每次拿到一個國家都去搜尋 陣列[國家] 存不存在,
不存在就將 Count 設為 1,存在就將 Count +1。
function findLand(inputArray){
let obj = []; //虛擬存不同的國家字串
let objAll = []; //存國家字串跟出現次數
for ( let i=0; i < inputArray.length; i++){
// distinct出不同國家
if ( !obj[inputArray[i].Land] ){
obj[inputArray[i].Land] = 1;
objAll.push({Country:inputArray[i].Land,Count:obj[inputArray[i].Land]});
}
else{
//存國家跟次數
for (var j=0; j < objAll.length; j++){
if( objAll[j].Country === inputArray[i].Land ){
objAll[j].Count += 1;
}
}
}
}
return objAll;
}
然後我們要驗證這個函數會不會 work,
所以這樣寫:
let countryCount = findLand(players);
for ( let i=0; i<countryCount.length; i++){
console.log(`${countryCount[i].Country} 有 ${countryCount[i].Count}`);
}
看起來有成功 distinct 出不同國家及數量,
這個函數真的滿好用的,
我自己用很多次XD
這邊是本日最後一個關卡了,
其實不難,讓我們勇敢的上吧XD
根據值不同要做不同事,
有一個好用的東西叫 switch case,(應該幾乎所有程式語言都有這個東西)
讓我們先用 JavaScript 寫一下:
switch(event.target.value){
case 1:
console.log(" 1 有被點擊到");
break;
case 2:
console.log(" 2 有被點擊到");
break;
default:
console.log("default");
break;
}
嗯?為什麼一直走到 default 的邏輯?
該不會是 type 不一樣吧!
讓我們看看 event.target.value 的 type 是什麼吧!
console.log(`event.target.value 的 type 是 ${typeof(event.target.value)}`);
抓到了!switch 比的值是數字,
但 event.target.value 是 string 型態,
所以前面要用 parseInt 轉換成整數。
switch(parseInt(event.target.value)){
case 1:
console.log(" 1 有被點擊到!");
break;
case 2:
console.log(" 2 有被點擊到!");
break;
default:
console.log("default");
break;
}
耶,正常比對了,
那我們繼續往下寫吧。
function contentShow(event){
// console.log(`所點擊的值為: ${event.target.value}`);
// console.log(`event.target.value 的 type 是 ${typeof(event.target.value)}`);
switch(parseInt(event.target.value)){
case 1:
// console.log(" 1 有被點擊到!");
tableHTMLStr = `<tr><th>名次</th><th>選手</th><th>差距(分)</th></tr>`; // 表格標頭
for ( let i=1; i<players.length; i++){ // 要從第 2 個開始,因為小戴自己是基準
// 其實可以合成 1 行,拆 2 行只是方便閱讀
tableHTMLStr += `<tr><td>${players[i].Rank}</td><td>${players[i].Speler}</td>`;
tableHTMLStr += `<td>${players[0].Punten - players[i].Punten}</td></tr>`;
}
break;
case 2:
// console.log(" 2 有被點擊到!");
tableHTMLStr = `<tr><th>國家</th><th>選手數</th></tr>`; // 表格標頭
for ( let i=0; i<countryCount.length; i++){
tableHTMLStr += `<tr><td>${countryCount[i].Country}</td><td>${countryCount[i].Count}</td></tr>`;
}
break;
default:
console.log("default");
break;
}
tableElement.innerHTML = tableHTMLStr;
}
耶!本日打完收工!
其實本日的 addEventListener("click")
有更好的做法是 addEventListener("change")
偵測值的改變才去做,而不是 click 到就要做,
但今天是複習 addEventListener 的感覺,
還是先用起手式 click 開始XD