iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0
Modern Web

JS30 x 鐵人30 x MDN doc系列 第 12

[Day12] - Key Sequence Detection(JS30 x 鐵人 30 x MDN)

  • 分享至 

  • xImage
  •  

按鍵佇列檢測,當輸入通關密語螢幕上則會出現獨角獸

又是打開 index-START.html 不知道要做什麼事的一題,只好看一下影片看要幹嘛(p.s.我只有完全無頭緒才會點開影片看,或是最後完成才看一下作者的寫法),作者這邊引用一個他寫好cornify.js,主要功能是在使用者輸入正確的通關密語時,會執行cornify_add()並在螢幕上隨機位置增加一個 BINGO 圖案以及恭喜訊息,答對次數則紀錄於cookie cornify中。

  1. 首先我們先宣告一個變數secretWords存放我們設定的通關密語(答案)字串。
const secretWords = "tim";
  1. 接著宣告一個陣列來存放使用者每次輸入的按鍵。
const arr = [];
  1. 既然要偵測輸入訊息,那肯定是使用KeyboardEvent,我們針對這整個 html 新增一個針對keyup按鍵彈起的事件監聽器,為什麼不是用keypress or keydown呢?那是因為使用這兩個,當按鍵按著時會連續觸發事件,所以改用彈起才觸發事件,我們可以先印KeyboardEvent: key property出來觀察看看,應該是沒有問題的。
document.addEventListener("keyup", (e) => {
  console.log(e.key);
});
  1. 接著我們要處理判斷使用者輸入的訊息是不是跟答案穩合的部分,但因為會持續輸入每次都必須將這次輸入的值Array.push()到陣列內存放,總不能讓我們的陣列無限增長,然後再取後面的值來跟答案比對。
  • 所以每次在 push 之前我們先判斷原本的Array: length是不是已經跟答案長度String: length相同,如果相同的話我們用Array.prototype.splice()將最前面輸入(相對比較舊)的給刪掉。
  • 最後把陣列用Array.prototype.join()組合成字串去跟答案判斷是不是一樣,如果是的話就執行一次回答正確要告知使用者的事cornify_add();
document.addEventListener("keyup", (e) => {
  // 如果長度已經跟答案相同把最舊的刪掉
  if (arr.length === secretWords.length) arr.splice(0, 1);
  // 把這次輸入的按鍵推進陣列
  arr.push(e.key);
  // 把陣列組成字串 跟 答案 判斷是否相同
  if (arr.join("").toLocaleLowerCase() === secretWords.toLocaleLowerCase()) {
    cornify_add();
    //每次都印出來觀察
    console.log(arr);
  }
});

作者這邊在刪除第一項這邊用了相對高深的語法,這要對Array.prototype.splice()的每一項參數都非常熟悉才會比較好理解,只有在陣列長度超過答案長度時,第二個參數deleteCount參數才會為 1,才會從 -(答案長度)減 1 的位置,也就是最前項刪除deleteCount個 item,這樣的話就不會多一個判斷式,而是每次都執行array.splice行為,但有沒有刪就是看傳入參數而定。

arr.push(e.key);
arr.splice(-secretWords.length - 1, arr.length - secretWords.length);

👉Github Demo 頁面 👈 通關密語修改為:Tim

👉 好想工作室 15th 鐵人賽看板 👈

參考資料

  1. Javascript 30 官網
    https://javascript30.com/
  2. MDN 官網
    https://developer.mozilla.org/en-US/

上一篇
[Day11] - Custom Video Player(JS30 x 鐵人 30 x MDN)
下一篇
[Day13] - Slide in on Scroll(JS30 x 鐵人 30 x MDN)
系列文
JS30 x 鐵人30 x MDN doc30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言