一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

HTML怎么做打字测速_HTML打字速度测试工具实现最全

时间:2026-07-22 10:49:59 编辑:袖梨 来源:一聚教程网

contenteditable捕获实时打字行为需组合keydown(记录按键时间/键值/光标位置)与input(比对textContent校验正确性),禁用spellcheck,清除零宽字符,并用performance.now()精准计时计算WPM。

怎么用 contenteditable 捕获实时打字行为

原生 inputtextarea 无法精确监听单个按键(比如按住不放会重复触发),而打字测速必须区分「按键次数」「是否正确」「光标位置」。用 contenteditable + keydown + input 组合才是可靠方案。

关键点:只在 keydown 中记录按键时间、键值和期望字符;在 input 触发后比对实际输入内容与目标文本的对应位置。避免用 keypress(已废弃)或单纯监听 input(无法区分删除/粘贴/方向键)。

  • contenteditable="true" 的容器要设 spellcheck="false",禁用拼写检查干扰光标定位
  • 每次 keydown 时,用 getSelection().anchorOffset 获取当前光标位置,比字符串索引更准确
  • 粘贴(paste)事件必须单独拦截并手动校验,否则会跳过多个字符导致 WPM 计算失真

如何计算有效 WPM(Words Per Minute)

WPM 不是简单用「正确字符数 ÷ 5 ÷ 分钟」。真实场景中,1 个 word = 5 个字符(含空格),但用户删改、回退、误按都得剔除——否则 100 字错 30 个还显示 40 WPM,完全失真。

正确做法:以「目标文本中已被正确覆盖的连续字符段」为单位统计。例如目标是 "the quick",用户输入 "th quik",只计前 2 个字符("th")+ 后 4 个("quik"),中间空格错位导致断开,不合并。

立即学习“前端免费学习笔记(深入)”;

  • 每秒更新一次:用 performance.now() 记录开始时间,避免 Date.now() 受系统时间调整影响
  • 错误字符不计入总数,但错误本身要计时(即“耗时”包含纠错时间)
  • 连续 3 秒无输入自动暂停计时,防止挂机虚高

为什么 innerTexttextContent 在测速中结果不同

innerText 读取 contenteditable 内容会丢失换行、折叠空白、甚至因 CSS display: none 隐藏内容而漏字;而 textContent 返回原始 DOM 文本节点内容,严格对应目标字符串索引。

例如目标文本含两个空格:"a b",用户输入 "a b",用 innerText 比较会认为「中间空格数不对」,但实际只是渲染折叠了——这会导致误判错误率。

  • 始终用 textContent 获取用户当前输入内容
  • 比对前先用正则 /[u200B-u200DuFEFF]/g 清除零宽字符(复制粘贴常带入)
  • 目标文本也需用相同方式预处理,保持两端一致

移动端软键盘触发后光标错位怎么修复

iOS Safari 和部分安卓 WebView 中,软键盘弹出后 getSelection().anchorOffset 常返回 0 或错误值,导致字符比对从头开始,全盘错乱。

根本原因:软键盘改变视口,重排布局导致 Selection API 失效。不能依赖事件时机,得用兜底策略。

  • 监听 focusinblur,在聚焦瞬间用 setTimeout(() => {}, 0) 延迟获取光标位置
  • 若两次获取差值 > 1,降级为用 textContent.length 估算光标(仅限单行场景)
  • 禁用 user-scalable=no,否则 iOS 键盘缩放会进一步扰乱坐标计算

真正难的不是算 WPM,而是让每一次空格、每一次退格、每一次粘贴都反映真实输入节奏——浏览器对编辑行为的抽象太粗,必须自己补全语义。

热门栏目