如何实现点击触发的多轮逐字显示对话切换系统?
实现可多次切换的逐字显示对话系统
核心修改思路
- 定义多组对话内容,存储为数组支持循环切换
- 封装文本初始化和逐字显示的函数,实现逻辑复用
- 绑定按钮点击事件,完成清空容器、切换对话、重新渲染的完整流程
修改后的HTML代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>对话系统</title> <link href="style.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="text"></div> <button id="textchanger">继续</button> <script src="script.js"></script> <script src="https://replit.com/public/js/replit-badge.js" theme="blue" defer></script> </body> </html>
修改后的CSS代码
html, body { height: 100%; width: 100%; } .text span { opacity: 0; } .text span.revealed { opacity: 1; } .text span.green { color: #27ae60; } .text span.red { color: #ff0000; } body { background: #3498db; padding: 3em; font-family: 'Sora', monospace; } .text { font-size: 6vw; word-spacing: 0.2em; margin: 0 auto; background: #fff; padding: 1em; border-bottom: 1vw solid #0e6dad; position: relative; line-height: 1.2em; } #textchanger { margin-top: 2em; padding: 0.8em 2em; font-size: 1.2em; border: none; background: #0e6dad; color: white; cursor: pointer; }
修改后的JavaScript代码
const container = document.querySelector(".text"); const btn = document.getElementById('textchanger'); const speeds = { pause: 400, slow: 120, normal: 50, fast: 20, superFast: 10 }; // 多组对话内容,每组对应一段完整对话 const dialogues = [ [ { speed: speeds.slow, string: "this is a test" }, { speed: speeds.pause, string: "", pause: true }, { speed: speeds.normal, string: "pls help me" }, { speed: speeds.fast, string: "idk what im doing", classes: ["red"] }, { speed: speeds.normal, string: ":(" } ], [ { speed: speeds.normal, string: "Great! Now we can switch dialogues" }, { speed: speeds.pause, string: "", pause: true }, { speed: speeds.slow, string: "Click the button again to see next one" }, { speed: speeds.fast, string: "Yay!", classes: ["green"] } ], [ { speed: speeds.superFast, string: "Loop back to start after this!" }, { speed: speeds.pause, string: "", pause: true }, { speed: speeds.normal, string: "Let's go again!" } ] ]; let currentDialogueIndex = 0; // 清空文本容器 function clearContainer() { container.innerHTML = ''; } // 初始化当前对话的字符元素 function initDialogue(textLines) { const characters = []; textLines.forEach((line, index) => { if (index < textLines.length - 1) { line.string += " "; } line.string.split("").forEach((character) => { const span = document.createElement("span"); span.textContent = character; container.appendChild(span); characters.push({ span: span, isSpace: character === " " && !line.pause, delayAfter: line.speed, classes: line.classes || [] }); }); }); return characters; } // 逐字显示字符 function revealOneCharacter(list) { if (!list.length) return; const next = list.splice(0, 1)[0]; next.span.classList.add("revealed"); next.classes.forEach((c) => { next.span.classList.add(c); }); const delay = next.isSpace && !next.pause ? 0 : next.delayAfter; setTimeout(() => { revealOneCharacter(list); }, delay); } // 加载并显示当前对话 function loadCurrentDialogue() { clearContainer(); const currentLines = dialogues[currentDialogueIndex]; const chars = initDialogue(currentLines); setTimeout(() => { revealOneCharacter(chars); }, 600); } // 按钮点击切换对话 btn.addEventListener('click', () => { currentDialogueIndex = (currentDialogueIndex + 1) % dialogues.length; loadCurrentDialogue(); }); // 初始化显示第一组对话 loadCurrentDialogue();
关键修改说明
- 多组对话管理:新增
dialogues数组,将不同对话内容分组存储,后续只需在数组中添加新组即可扩展对话。 - 函数封装:拆分出
clearContainer、initDialogue等独立函数,避免重复代码,方便维护。 - 循环切换逻辑:通过
currentDialogueIndex跟踪当前对话,点击按钮时用取模运算实现对话循环切换。 - 修复按钮绑定问题:修正原代码中按钮ID不匹配的错误,成功绑定点击事件触发切换。
内容的提问来源于stack exchange,提问作者BNC
相关产品推荐
相关产品推荐

