Last active
September 29, 2025 10:12
-
-
Save omrilotan/a11be76ef0b0877a5257692863fe0b18 to your computer and use it in GitHub Desktop.
The Konami Code is a famous cheat sequence of button presses (↑↑↓↓←→←→BA) from 1980s Konami video games that unlocks hidden features or bonuses. This function listens for the Konami Code sequence and triggers a callback when detected.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * This function listens for the Konami Code sequence and triggers a callback when detected. | |
| * The Konami Code is a famous cheat sequence of button presses (↑↑↓↓←→←→BA) from 1980s Konami video games that unlocks hidden features or bonuses. | |
| * @param {Function} callback - The function to call when the Konami Code is entered. | |
| * @param {Object} [options={}] - Options for the listener. | |
| * @param {boolean} [options.once=false] - If true, the listener will be removed after the first successful entry. | |
| * @param {number} [options.timeout=0] - Time in milliseconds to reset the sequence if no key is pressed (must be >= 0). | |
| * @param {HTMLElement|Document} [options.target=document] - The target element to attach the listener to. | |
| * @returns {Function} A function to remove the event listener. | |
| * @throws {TypeError} When callback is not a function or timeout is negative. | |
| */ | |
| function konamiCode( | |
| callback, | |
| { once = false, timeout = 0, target = document } = {}, | |
| ) { | |
| if (typeof callback !== "function") | |
| throw new TypeError("Callback must be a function"); | |
| timeout = Number(timeout); | |
| if (isNaN(timeout) || timeout < 0) | |
| throw new TypeError("Timeout must be a non-negative number"); | |
| const KONAMI_SEQUENCE = [ | |
| "ArrowUp", | |
| "ArrowUp", | |
| "ArrowDown", | |
| "ArrowDown", | |
| "ArrowLeft", | |
| "ArrowRight", | |
| "ArrowLeft", | |
| "ArrowRight", | |
| "KeyB", | |
| "KeyA", | |
| ]; | |
| const sequence = []; | |
| let timer = null; | |
| function reset() { | |
| sequence.length = 0; | |
| if (timer) { | |
| clearTimeout(timer); | |
| timer = null; | |
| } | |
| } | |
| function keydownHandler(event) { | |
| sequence.push(event.code); | |
| if (timeout > 0) { | |
| if (timer) clearTimeout(timer); | |
| timer = setTimeout(reset, timeout); | |
| } | |
| if (!sequence.every((key, index) => key === KONAMI_SEQUENCE[index])) { | |
| reset(); | |
| return; | |
| } | |
| if (sequence.length < KONAMI_SEQUENCE.length) return; | |
| reset(); | |
| if (once) target.removeEventListener("keydown", keydownHandler); | |
| callback(); | |
| } | |
| target.addEventListener("keydown", keydownHandler, { passive: true }); | |
| return function remove() { | |
| reset(); | |
| target.removeEventListener("keydown", keydownHandler); | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment