You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态输入框focus与blur异常:OTP自动跳转功能失效

OTP输入框自动聚焦失效的解决方案

问题出在你用了onchange事件——数字类型的输入框,onchange只有在输入框失去焦点时才会触发,所以输入数字后不会立刻执行聚焦下一个的逻辑,自然看不到效果。

另外还有两个小问题需要修正:

  • max-length是错误的属性名,正确的应该是maxlength(没有连字符)
  • 循环里给所有输入框设置了同一个id="otp-input",这会导致DOM元素id重复,不符合规范

下面是修正后的代码:

const OTP_LENGTH = 6;
const otpContainer = document.getElementById('otp-container');
const textInputs = [];

for (let i = 0; i < OTP_LENGTH; ++i) {
  const input = document.createElement('input');
  input.setAttribute('maxlength', '1'); // 修正属性名
  input.type = 'number';
  input.setAttribute('id', `otp-input-${i}`); // 设置唯一id
  input.setAttribute('data-otp-pos', i);
  textInputs.push(input);
  otpContainer.appendChild(input);
  
  input.onfocus = () => console.log("Focus", i);
  input.onblur = () => console.log("Blur", i);
  
  // 用oninput代替onchange,内容变化立即触发
  input.oninput = (e) => {
    const target = e.target;
    const position = parseInt(target.dataset.otpPos, 10);
    // 确保输入内容有效且不是最后一个输入框
    if (target.value && position !== OTP_LENGTH - 1) {
      const nextInput = textInputs[position + 1];
      nextInput.focus(); // 直接聚焦下一个,无需手动blur当前框
    }
  };
  
  // 可选:支持删除键回到上一个输入框
  input.onkeydown = (e) => {
    const target = e.target;
    if (e.key === 'Backspace' && !target.value) {
      const position = parseInt(target.dataset.otpPos, 10);
      if (position > 0) {
        textInputs[position - 1].focus();
      }
    }
  };
}

关键改动说明:

  1. 替换事件类型:用oninput替代onchange,输入框内容一变化就触发事件,确保输入数字后立刻执行聚焦逻辑。
  2. 修正属性错误:把max-length改成maxlength,确保输入框只能输入1个字符。
  3. 唯一id:每个输入框的id加上索引后缀,避免id重复问题。
  4. 优化聚焦逻辑:不需要手动调用target.blur(),直接nextInput.focus()就会让当前输入框自动失去焦点,简化代码。
  5. 新增删除键支持:可选功能,当删除空输入框的内容时,自动聚焦到上一个输入框,提升用户体验。

测试后,输入数字会立刻跳转到下一个输入框,删除时也能回到上一个,完全符合需求。

内容的提问来源于stack exchange,提问作者Apoorv Kansal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:53:13