
本文介绍如何使用原生 javascript 将多个单字符 otp 输入框(如 6 位验证码)实时合并为一个完整字符串,并同步填充至用户名和密码两个表单字段,支持键盘导航、粘贴解析与自动聚焦。
本文介绍如何使用原生 javascript 将多个单字符 otp 输入框(如 6 位验证码)实时合并为一个完整字符串,并同步填充至用户名和密码两个表单字段,支持键盘导航、粘贴解析与自动聚焦。
在构建登录或验证流程时,常需用户输入多位数字(如短信验证码、PIN 码),并将其作为统一凭证用于用户名和密码字段(例如临时通行码场景)。传统做法依赖 jQuery 或冗余监听逻辑,易出错且维护成本高。本文提供一套轻量、健壮、无框架依赖的原生实现方案。
Skill
一款AI工具,主要用于后台本地运行 Codex,即时回执并保存日志与补丁产物,可选 Telegram 通知,支持显式工作目录,适合需要提升相关任务效率的用户。
下载
核心思路
完整可运行示例
<meta charset="UTF-8"><title>PIN 合并输入示例</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"><style>
.flex { display: flex; gap: 8px; }
.pin > input {
text-align: center;
width: 2.5rem;
height: 2.5rem;
font-size: 1.2rem;
border: 1px solid #ced4da;
border-radius: 4px;
outline: none;
transition: border-color 0.2s;
}
.pin > input:focus { border-color: #0d6efd; box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); }
</style><div class="container">
<h4>复制以下任意 PIN 码粘贴到下方输入框:</h4>
<pre class="bg-light p-2 rounded">123329<br>6 5 0 3 2 1<br>444-998<br>x1A23z<br>12
<script>
// DOM 工具函数(简洁安全)
const els = (sel, par = document) => par.querySelectorAll(sel);
const el = (sel, par = document) => par.querySelector(sel);
// 获取目标字段
const elUN = el('[name="username"]');
const elPW = el('[name="password"]');
// 处理每组 PIN 输入框(支持多组扩展)
els('.pin').forEach(elGroup => {
const inputs = [...els('input[name="pin[]"]', elGroup)];
const len = inputs.length;
const handlePaste = (ev) => {
ev.preventDefault();
const clip = ev.clipboardData.getData('text');
const pin = clip.replace(/[\s\-]/g, ''); // 清洗空格与连字符
const chars = [...pin];
inputs.forEach((inp, i) => inp.value = chars[i] ?? '');
inputs[Math.min(len - 1, chars.length - 1)]?.focus();
};
const handleInput = () => {
const PINValue = inputs.reduce((acc, inp) => acc + inp.value, '');
elUN.value = PINValue;
elPW.value = PINValue;
};
const handleKeydown = (ev) => {
const idx = inputs.indexOf(ev.target);
if (ev.key === 'Backspace' && !ev.target.value && idx > 0) {
inputs[idx - 1].focus();
}
};
const handleKeypress = (ev) => {
const idx = inputs.indexOf(ev.target);
if (ev.key.length === 1 && idx < len - 1 && ev.target.value) {
inputs[idx + 1].focus();
}
};
// 绑定事件
inputs.forEach(inp => {
inp.addEventListener('paste', handlePaste);
inp.addEventListener('input', handleInput);
inp.addEventListener('keydown', handleKeydown);
inp.addEventListener('keypress', handleKeypress);
});
});
</script>
关键注意事项
通过本方案,你获得了一个高性能、无障碍友好、可复用的 PIN 合并组件——无需外部依赖,开箱即用,且易于集成进任何现代前端项目。