JS实现6位验证码输入焦点跳转报focus未定义TypeError错误如何解决
输入6位验证码时,控制台抛出如下错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'focus')
说明:该验证码功能不涉及服务端数据交互,仅为实现前端UI交互效果的原生JavaScript代码,原始实现代码如下:
let codes = document.querySelectorAll('.code') codes[0].focus() codes.forEach(function (code, idx) { code.addEventListener('keydown', function (e) { if (e.key >= 0 && e.key <= 9) { codes[idx].value = '' setTimeout(() => codes[idx + 1].focus(), 10) } else if (e.key === 'Backspace') { setTimeout(() => codes[idx - 1].focus(), 10) } }) })
报错原因
代码未做数组边界校验,两个场景会访问到不存在的DOM元素:
- 当光标在最后一个验证码输入框(索引为
codes.length - 1)时输入数字,代码会尝试访问codes[idx + 1],该索引超出数组长度范围,返回值为undefined,调用focus()方法直接报错 - 当光标在第一个验证码输入框(索引为0)时按下退格键,代码会尝试访问
codes[idx - 1]即codes[-1],该索引不存在,返回值为undefined,调用focus()方法同样会报错
修复代码
在执行聚焦操作前增加边界判断,仅当目标输入框存在时才调用focus方法,同时补充了key值的类型判断避免隐式转换问题,修改后代码如下:
const codes = document.querySelectorAll('.code') codes[0].focus() codes.forEach((code, idx) => { code.addEventListener('keydown', (e) => { if (e.key >= '0' && e.key <= '9') { codes[idx].value = '' setTimeout(() => { // 最后一位输入后不再尝试向后聚焦 if (idx < codes.length - 1) { codes[idx + 1].focus() } }, 10) } else if (e.key === 'Backspace') { setTimeout(() => { // 第一位按退格不再尝试向前聚焦 if (idx > 0) { codes[idx - 1].focus() } }, 10) } }) })
内容的提问来源于stack exchange,提问作者Sazzad Hossain Nibir
相关产品推荐
相关产品推荐

