[JS30筆記]-Day12 Key Sequence Detection (KONAMI CODE)
今天要練習偵測、驗證鍵盤輸入內容序列。也能學會如何埋彩蛋在網頁上,讓使用者輸入秘密指令後,看到驚喜的畫面。👾👀
說到 KONAMI CODE (↑↑↓↓←→←→BA START)這個東西,大家應該都不陌生,連從小沒在打電動的我,都有聽過這串指令。
剛剛去搜尋了它的由來,覺得十分有趣,原來一開始是不小心的啊~
後來有很多網頁也會採用這段指令,在網頁上做一些小彩蛋給使用者驚喜。
目前能找到的例子有 go skills 這個網站,只要輸入 ↑↑↓↓←→←→BA,就會跳出這個小精靈遊戲,破關即有機會獲得優惠券。
今天要練習的範例是將秘密指令設定為一串字串。
想了解該如何偵測到使用者在瀏覽器開啟網頁後,輸入了秘密指令,就讓我們繼續看下去~
學習重點
e.key
.splice()
.join('')
.includes()
觀察範例檔案初始狀態
範例檔案中沒有 html 前端介面,只有預先載入一支 cornify.js,等等就能知道它的用途了~ 🦄🌈
<script type="text/javascript" src="https://www.cornify.com/js/cornify.js"></script>
解決思路
一、預設秘密指令內容,並偵測使用者輸入的字串內容
二、處理使用者輸入的字串陣列長度,以方便下一步比對
三、比對使用者輸入的字串是否與預設的秘密指令相符
一、預設秘密指令內容,並偵測使用者輸入的字串內容
- 預設秘密指令為 ‘wesbos’
- 對 window 監聽 keyup event,可以利用
e.key
取得使用者按下按鍵的值 - 再將它們 push 到預設的空陣列 pressed 裡面
console.log(pressed)
就能看到輸入的值所組成的陣列 :
二、處理使用者輸入的字串陣列長度,以方便下一步比對
此步驟利用 .splice
做了兩件事 :
- 控制陣列內的字數,保持不超過 secretCode 長度的字數
- 當字數多於 secretCode 長度,新輸入的字會從最後面新增,最前面的字則會被刪除
在字串陣列還沒用 .splice
處理之前,陣列的長度會像這樣無限增加 :
為了方便進一步比對,我們需要先將它用 .splice
方法進行處理。
.splice()
方法 : 可以藉由刪除既有元素並/或加入新元素來改變一個陣列的內容。
.splice(要插入或刪除的索引位置, 要刪除的元素數量, 要插入的元素內容)
我們只需要使用它的刪除功能,所以只會用到前兩個參數。
pressed.spliced(-secretCode.length -1, pressed.length - secretCode.length);
第二個參數為「要刪除的元素數量」,所以是利用 pressed 長度減去 secretCode 長度,得到多於的數量,就是我們要刪除的,這部分較好理解。
但第一個參數「要插入或刪除的索引位置」 帶入 -secretCode.length -1
讓我花最多時間理解。
參考了他人的筆記 :
「演算法設置 : 由於start
為負數時會從最後一個開始算起的下一個計算,所以當start
為-1
時,起始位置是最後一個的下一個,此時不會有資料被刪除,當起始位置為 -2 時才會刪除最後一個;同理若要刪除第一個時,則要設置為-n -1
。」
來源 :
但如果已知要從第一項開始刪除,是否直接帶入 0 也可以呢?
帶入 -n-1 是否可以避免什麼樣的情況?
或許是因為我對演算法還不夠了解,希望日後能漸漸體會這個 -n-1 的奧秘😅
經過 .splice()
的處裡後,陣列就會維持在不超過一定字數的長度,超過的話,每新增一個,第一個就會被移除~
再加上下面第三步驟做比對,我們就能在偵測到使用者輸入完整指令時(紅色打勾處),觸發其他驚喜事件囉~
三、比對使用者輸入的字串是否與預設的秘密指令相符
- 利用
join('')
來將陣列內一個個字,合併成一個完整字串 - 再利用
includes()
來比對字串是否與 secretCode 相符 - 比對結果為 true 的話,就可以在這邊觸發要給使用者的驚喜
- 範例中,因為剛開始有載入一支 cornify.js,我們可以在比對結果為 true 之後觸發
cornify_add()
這個事件,只要每輸入一次 secretCode,畫面上就會多出一個閃亮亮的獨角獸或彩虹圖案🤗哈哈哈
今天的練習就到這邊結束囉~
完整 JS 程式碼
const pressed = [];const secretCode = 'wesbos';window.addEventListener('keyup', (e) => { pressed.push(e.key); pressed.splice(-secretCode.length - 1, pressed.length - secretCode.length); if (pressed.join('').includes(secretCode)) { cornify_add(); }});