JavaScript自定义键盘输入问题:字符同时写入多个输入框
自定义键盘输入异常问题
自定义键盘需要将按键字符输入选中的input框,单独选第一个输入框时功能正常,但依次选第二个(邮箱)、第三个(密码)输入框后,按键字符会同时写入所有之前选中过的输入框。将输入框传入keyToInput函数时能正确识别,但在keyValue.forEach()后打印field,会发现所有三个输入框都被选中,推测问题出在forEach()的使用上,但尝试多种方法仍无法解决。
输入框HTML代码
<input type="text" placeholder="Name" id="name" class="form-control" name="name" required> <input type="text" placeholder="Email" id="email_address" class="form-control" name="email" required> <input type="password" placeholder="Password" id="password" class="form-control" name="password" required maxlength="5">
键盘模态框HTML代码
{{--KEYBOARD KEYPAD--}} <!-- Modal --> <div class="modal fade animate" id="keyPadModal" tabindex="-1" role="dialog" aria-labelledby="keyPadModal" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content animate-bottom"> <div class="modal-body keyPadModal"> <div class="keypad-text"> <div id="keypad-keys"> {{--KeyPad WINDOW 1 UPPERCASE--}} <div id="key-win-uppercase" class="key-win"> <div class="key-line key-line-1"> <div class="keypad-text-key key-put" data-val="Q">Q</div> <div class="keypad-text-key key-put" data-val="W">W</div> <div class="keypad-text-key key-put" data-val="E">E</div> <div class="keypad-text-key key-put" data-val="R">R</div> <div class="keypad-text-key key-put" data-val="T">T</div> <div class="keypad-text-key key-put" data-val="Y">Y</div> <div class="keypad-text-key key-put" data-val="U">U</div> <div class="keypad-text-key key-put" data-val="I">I</div> <div class="keypad-text-key key-put" data-val="O">O</div> <div class="keypad-text-key key-put" data-val="P">P</div> </div> </div> </div> </div> </div> </div> </div> </div>
原始JavaScript代码
const inputField = document.querySelectorAll("input"); const keyValue = document.querySelectorAll(".key-put"); function keyToInput(field) { keyValue.forEach(function (el) { el.addEventListener("click", function (e) { if (e.target.getAttribute("data-val")) { flashKey(e.target); const inp = el.getAttribute("data-val"); console.log(inp); console.log(field); //field.value = field.value + inp; } else { console.log("no value"); } }); }); } inputField.forEach(function (input) { input.addEventListener("click", function (element) { $("#keyPadModal").modal("show"); keyToInput(element.target); }); });
问题根源
每次点击输入框时,都会给键盘按键重复绑定点击事件。第一次点击姓名输入框,按键绑定了写入姓名框的事件;第二次点击邮箱输入框,又给按键绑定了写入邮箱框的事件;第三次点击密码框,再绑定写入密码框的事件。这样按键被点击时,所有绑定过的事件都会执行,导致字符同时写入多个输入框。
修复方案
采用全局变量记录当前激活的输入框,只给按键绑定一次点击事件,避免重复绑定:
const inputField = document.querySelectorAll("input"); const keyValue = document.querySelectorAll(".key-put"); let currentInput = null; // 存储当前选中的输入框 // 仅绑定一次按键点击事件 keyValue.forEach(el => { el.addEventListener("click", e => { if (!currentInput) return; const keyVal = e.target.getAttribute("data-val"); if (keyVal) { flashKey(e.target); currentInput.value += keyVal; } }); }); // 输入框点击时更新当前选中的输入框并打开模态框 inputField.forEach(input => { input.addEventListener("click", function() { currentInput = this; $("#keyPadModal").modal("show"); }); });
优化说明
- 用
currentInput变量跟踪当前激活的输入框,避免每次点击输入框都重复绑定事件。 - 按键事件只初始化一次,触发时直接向
currentInput写入字符,彻底解决多输入框同时写入的问题。 - 简化了原有的
keyToInput函数逻辑,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者staff_sgn
相关产品推荐
相关产品推荐

