当前位置: 首页 > news >正文

JS+H5打字练习器

实现功能

1.导入.TXT文件到打字练习内容(部分浏览器可能出于安全问题限制了这一步操作)
2.输入文本到打字练习内(弹出输入框,将要练习的内容输入至输入框)
3. 开始练习,并根据正误在打字练习内容文本上修改颜色(某个字正确显示绿色,某个字错误,显示红色,某个字没有打显示灰色)
4.开始练习、结束练习,全部输入完成后自动结束练习,也可提前手动结束练习,结束练习后弹窗用显示时和正确率。(区别在于一个全部输入完成且全部正确,一个提前结束无其他条件)

效果图

在这里插入图片描述在这里插入图片描述

分析

HTML 结构解析

  1. 根元素<!DOCTYPE html> 声明文档类型为HTML。
  2. html 元素:包含整个页面的内容,并设置语言为中文(lang="zh-CN")。
  3. head 元素:包含页面的元数据,如字符集(charset="UTF-8")、视口设置(viewport)和标题(<title>)。
  4. style 元素:包含页面的CSS样式。
    • 设置页面背景颜色、字体、布局样式等。
  5. body 元素:包含页面的可见内容。
    • 使用Flexbox布局使内容居中。
  6. .container:包含文本输入框和按钮,并设置样式。
  7. .buttons:包含一组按钮,并设置布局样式。
  8. .text-to-type:包含待输入的文本,并设置样式。
  9. input 元素:一个文本输入框,用于用户输入。

JavaScript 解析

  1. 变量声明

    • textToType:获取待输入文本的DOM元素。
    • inputText:获取用户输入文本的DOM元素。
    • importTextBtnaddTextBtnstartPracticeBtnendPracticeBtn:获取按钮的DOM元素。
    • originalText:存储原始待输入的文本。
    • startTime:存储开始练习的时间。
    • alertCount:存储弹窗次数。
    • correctCount:存储正确的字符数。
  2. inputText 输入事件监听器

    • 当用户在输入框中输入时,会触发此事件。
    • 获取用户当前输入的文本。
    • 初始化一个空字符串updatedText用于构建更新后的文本。
    • 如果startTime已设置,遍历原始文本和用户输入的文本:
      • 如果字符匹配,将字符标记为correct
      • 如果字符不匹配,将字符标记为wrong
    • 更新textToType的HTML内容。
    • 如果用户输入的文本与原始文本完全匹配,计算总用时和正确率,并通过弹窗显示结果。
    • 重置输入框和startTime
  3. importTextBtn 点击事件监听器

    • 创建一个文件输入元素,允许用户选择.txt文件。
    • 当文件被选中后,使用FileReader读取文件内容。
    • 读取完成后,将文本内容赋值给originalText并更新textToType
  4. addTextBtn 点击事件监听器

    • 弹出一个输入框让用户输入文本。
    • 如果用户输入了文本,将其赋值给originalText并更新textToType
  5. startPracticeBtn 点击事件监听器

    • 设置startTime为当前时间。
    • 清空输入框。
    • 更新textToType的HTML内容为原始文本。
  6. endPracticeBtn 点击事件监听器

    • 如果startTime已设置,计算总用时和正确率,并通过弹窗显示结果。
    • 重置startTime和输入框。

完成源代码

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>打字练习</title><style>body {font-family: Arial, sans-serif;background-color: #f0f0f0;display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;}.container {background-color: white;padding: 20px;border-radius: 15px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);max-width: 600px;width: 100%;text-align: center;}.buttons {display: flex;justify-content: space-around;margin-bottom: 20px;}.buttons button {background-color: black;color: white;border: none;border-radius: 5px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);padding: 10px 20px;cursor: pointer;font-size: 14px;}.text-to-type {color: gray;margin-bottom: 20px;font-size: 20px;}.text-to-type span.correct {color: green;}.text-to-type span.wrong {color: red;}input[type="text"] {width: 100%;padding: 10px;border-radius: 5px;border: 1px solid #ccc;font-size: 18px;}</style>
</head>
<body><div class="container"><div class="buttons"><button id="importText">导入文本</button><button id="addText">添加文本</button><button id="startPractice">开始练习</button><button id="endPractice">结束练习</button></div><div class="text-to-type" id="textToType">这是一个打字练习的例子</div><input type="text" id="inputText" placeholder="开始打字..." /></div><script>const textToType = document.getElementById('textToType');const inputText = document.getElementById('inputText');const importTextBtn = document.getElementById('importText');const addTextBtn = document.getElementById('addText');const startPracticeBtn = document.getElementById('startPractice');const endPracticeBtn = document.getElementById('endPractice');let originalText = textToType.innerText;let startTime = null;let alertCount = 0;let correctCount = 0;inputText.addEventListener('input', () => {const typedText = inputText.value;let updatedText = '';correctCount = 0;if (startTime) {for (let i = 0; i < originalText.length; i++) {if (i < typedText.length) {if (typedText[i] === originalText[i]) {updatedText += `<span class="correct">${originalText[i]}</span>`;correctCount++;} else {updatedText += `<span class="wrong">${originalText[i]}</span>`;}} else {updatedText += originalText[i];}}textToType.innerHTML = updatedText;}if (typedText === originalText && startTime) {const endTime = new Date();const timeTaken = ((endTime - startTime) / 1000).toFixed(2);const accuracy = ((correctCount / originalText.length) * 100).toFixed(2);alert(`总用时间: ${timeTaken} 秒\n正确率: ${accuracy}%`);alertCount++;if (alertCount < 3) {alert(`这是第 ${alertCount} 次弹窗`);}inputText.value = '';startTime = null;}});importTextBtn.addEventListener('click', () => {const fileInput = document.createElement('input');fileInput.type = 'file';fileInput.accept = '.txt';fileInput.onchange = e => {const file = e.target.files[0];const reader = new FileReader();reader.onload = event => {originalText = event.target.result.trim();textToType.innerText = originalText;};reader.readAsText(file);};fileInput.click();});addTextBtn.addEventListener('click', () => {const userInput = prompt('请输入要练习的文本:');if (userInput) {originalText = userInput.trim();textToType.innerText = originalText;}});startPracticeBtn.addEventListener('click', () => {startTime = new Date();inputText.value = '';textToType.innerHTML = originalText;});endPracticeBtn.addEventListener('click', () => {if (startTime) {const endTime = new Date();const timeTaken = ((endTime - startTime) / 1000).toFixed(2);const accuracy = ((correctCount / originalText.length) * 100).toFixed(2);alert(`练习结束\n总用时间: ${timeTaken} 秒\n正确率: ${accuracy}%`);startTime = null;inputText.value = '';} else {alert('请先开始练习!');}});</script>
</body>
</html>
http://www.lryc.cn/news/413189.html

相关文章:

  • windows系统关闭开机自检硬盘
  • 【多线程开发 5】实践使用Lock和Condition
  • 2.4-结构化并发:协程的结构化异常管理
  • Android 12.0 debug版本打开OEM解锁开关功能实现
  • linux用户组练习
  • [Docker][Docker Container]详细讲解
  • 塑造美好心灵,激发创造活力|第三届瓷艺中华“陶溪川杯”儿童青少年陶瓷作品展开展
  • 鸿蒙开发刷新单个item会闪一下处理
  • 您需要了解的有关 5G 的一切。
  • 【redis】初识redis入门,基础部署以及介绍
  • 数据库基础 -- 数据库约束
  • U盘文件或目录损坏无法读取?专业恢复策略全解析
  • dpdk实现udp协议栈
  • Shell编程——基础语法(2)和 Shell流程控制
  • Python基础教程(二)字符串和函数
  • 智算新风向丨趋动科技获中国信通院泰尔实验室首张智算资源池化能力泰尔测评证书
  • 计算机基础(Windows 10+Office 2016)教程 —— 第4章 计算机网络与Internet(上)
  • MES系统在数字化转型中的核心作用与影响
  • 装修施工注意事项
  • 【Docker学习记录】
  • 互联网政务应用安全管理规定
  • HarmonyOS开发商城首页实现
  • QtQuick Text-文本样式
  • 人工智能未来展望
  • Pymol开源版安装 新版 3.0 / 3.1 Windows安装Pymol开源版
  • 记录一次环境的安装
  • 浏览器用户文件夹详解 - WebData(八)
  • ijkplayer 自定义协议播放加密内容 Android
  • 【kill】Centos/Linux 如何杀死那该死的进程?
  • Cadence23学习笔记(十七)