如何在HTML/JS打字游戏中逐字符校验并对应变色?
打字游戏菜单逐字符颜色匹配问题
我正在开发一款打字游戏的菜单页面,页面里有两个目标单词(start和options),还有一个显示用户按键输入的TypeZone区域。需要实现:用户输入的每个字符与目标单词对应位置字符匹配时,该字符变绿色;不匹配则变红色。目前代码只能整体改变单词颜色,无法逐字符处理。
原代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Madimi+One&display=swap" rel="stylesheet"> <link rel="stylesheet" href="style.css"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Typo game</title> </head> <body> <label id="playerInput">start</label> <label id="options">options</label> <label id="TypeZone">sssssss</label> <script src="script.js"></script> </body> </html>
CSS
*{ font-family: "Madimi One", sans-serif; margin: 0; padding: 0; box-sizing: border-box; } body{ height: 100vh; background-color: black; } #playerInput{ position: absolute; top: 40%; left: 45%; transform: translate(-50% -50%); font-size: 3em; color: aliceblue; } #options{ position: absolute; top: 55%; left: 43%; transform: translate(-50% -50%); font-size: 3em; color: aliceblue; } #TypeZone{ position: absolute; top: 70%; left: 67%; transform: translate(-50% -50%); font-size: 3em; color: aliceblue; }
JavaScript
const start= document.querySelector("#playerInput"); const get_start = [...start.textContent] const options = document.querySelector("#options"); const get_options = [...options.textContent] let inputX = ""; let getInputX = true; const type = document.querySelector("#TypeZone") // get input from keyboard and display on screen document.addEventListener("keydown", function(event) { if (getInputX) { inputX += event.key; type.textContent = inputX; if (inputX.length >= get_options.length) { getInputX = false; } } if (get_start.includes(event.key)){ start.style.color ="green"; /// what i want to do is to turn letter green for each correct letter and so on } else{ start.style.color = "red"; } if (get_options.includes(event.key)){ options.style.color ="green"; /// } else{ options.style.color = "red"; } // if typed start or options >> start the game if (inputX === "start" || inputX === "options"){ window.location.href = "game.html"; } });
解决方案
要实现逐字符颜色控制,核心是把每个单词的字符拆成独立元素(比如<span>),这样就能单独修改每个字符的样式。
1. 修改HTML结构
将目标单词的每个字符包裹在<span>中:
<!DOCTYPE html> <html lang="en"> <head> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Madimi+One&display=swap" rel="stylesheet"> <link rel="stylesheet" href="style.css"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Typo game</title> </head> <body> <label id="playerInput"> <span>s</span><span>t</span><span>a</span><span>r</span><span>t</span> </label> <label id="options"> <span>o</span><span>p</span><span>t</span><span>i</span><span>o</span><span>n</span><span>s</span> </label> <label id="TypeZone"></label> <script src="script.js"></script> </body> </html>
2. 调整CSS
给新增的<span>添加基础样式,确保字符独立显示:
*{ font-family: "Madimi One", sans-serif; margin: 0; padding: 0; box-sizing: border-box; } body{ height: 100vh; background-color: black; } #playerInput, #options{ position: absolute; font-size: 3em; color: aliceblue; } #playerInput{ top: 40%; left: 45%; transform: translate(-50%, -50%); } #options{ top: 55%; left: 43%; transform: translate(-50%, -50%); } #TypeZone{ position: absolute; top: 70%; left: 67%; transform: translate(-50%, -50%); font-size: 3em; color: aliceblue; } /* 新增:每个字符独立控制 */ #playerInput span, #options span{ display: inline-block; transition: color 0.2s ease; /* 可选:添加颜色过渡动画 */ }
3. 重写JavaScript逻辑
跟踪用户输入的每个字符,对应到目标单词的位置,逐个判断匹配状态:
// 获取目标单词的所有字符元素 const startChars = document.querySelectorAll("#playerInput span"); const optionsChars = document.querySelectorAll("#options span"); const typeZone = document.querySelector("#TypeZone"); // 目标单词文本 const targetStart = "start"; const targetOptions = "options"; // 用户输入跟踪 let userInput = ""; document.addEventListener("keydown", function(event) { // 忽略功能键,只处理可打印字符和退格 const key = event.key; if (key.length !== 1 && key !== "Backspace") return; // 处理退格键 if (key === "Backspace") { userInput = userInput.slice(0, -1); typeZone.textContent = userInput; // 重置退格位置的字符颜色 resetCharColors(); // 重新检查现有输入的匹配状态 checkInputMatches(); return; } // 添加输入字符 userInput += key; typeZone.textContent = userInput; // 检查输入是否匹配目标单词 checkInputMatches(); // 完整匹配时跳转页面 if (userInput === targetStart || userInput === targetOptions) { window.location.href = "game.html"; } // 输入长度超过最长单词时重置 if (userInput.length > Math.max(targetStart.length, targetOptions.length)) { userInput = ""; typeZone.textContent = ""; resetCharColors(); } }); // 检查输入与两个目标单词的匹配状态,设置对应字符颜色 function checkInputMatches() { // 检查start单词 for (let i = 0; i < startChars.length; i++) { if (i < userInput.length) { startChars[i].style.color = userInput[i] === targetStart[i] ? "green" : "red"; } else { startChars[i].style.color = "aliceblue"; // 未输入的字符保持默认颜色 } } // 检查options单词 for (let i = 0; i < optionsChars.length; i++) { if (i < userInput.length) { optionsChars[i].style.color = userInput[i] === targetOptions[i] ? "green" : "red"; } else { optionsChars[i].style.color = "aliceblue"; } } } // 重置所有字符颜色为默认 function resetCharColors() { startChars.forEach(char => char.style.color = "aliceblue"); optionsChars.forEach(char => char.style.color = "aliceblue"); }
功能说明
- 每个输入的字符会同时对应两个目标单词的相同位置,匹配则变绿,不匹配变红
- 支持退格键删除输入,同时重置对应位置的字符颜色
- 输入长度超过最长单词(options,7个字符)时自动重置输入
- 完整输入start或options时跳转到游戏页面
内容的提问来源于stack exchange,提问作者simo_elatt
相关产品推荐
相关产品推荐

