输入框Back/Forward按钮异常:仅用按钮输入字符总是追加至末尾
问题分析与解决方案
问题原因
- 光标移动函数参数错误:
moveBack和moveForward中调用setSelectionRange时参数顺序完全搞反了。setSelectionRange(start, end)的正确逻辑是第一个参数为选中文本的起始位置,第二个为结束位置;当前代码把输入框内容长度作为第一个参数,导致光标实际没有定位到预期位置,而是选中了从末尾到目标位置的区域,后续修改值时浏览器默认追加到末尾。 - 字符输入逻辑未考虑光标位置:
setA/B/C/D函数直接用+=追加字符,不管当前光标在哪都直接加到字符串末尾;而键盘输入是浏览器原生处理,会自动在光标位置插入字符,因此表现正常。
解决方案
- 修复光标移动函数的
setSelectionRange参数,将起始和结束位置设为相同值(移动光标而非选中文本),同时增加边界判断,避免光标超出输入框内容范围。 - 重写字符输入函数,先获取当前光标位置,在对应位置插入字符,然后将光标定位到插入后的下一位,保证输入行为符合预期。
修改后的完整代码
JavaScript 代码
function getInputSelection(el) { var start = 0, end = 0, normalizedValue, range, textInputRange, len, endRange; if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") { start = el.selectionStart; end = el.selectionEnd; } else { range = document.selection.createRange(); if (range && range.parentElement() == el) { len = el.value.length; normalizedValue = el.value.replace(/\r\n/g, "\n"); textInputRange = el.createTextRange(); textInputRange.moveToBookmark(range.getBookmark()); endRange = el.createTextRange(); endRange.collapse(false); if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) { start = end = len; } else { start = -textInputRange.moveStart("character", -len); start += normalizedValue.slice(0, start).split("\n").length - 1; if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) { end = len; } else { end = -textInputRange.moveEnd("character", -len); end += normalizedValue.slice(0, end).split("\n").length - 1; } } } } return { start: start, end: end }; } function setBack() { var elem = document.getElementById('user'); var selection = getInputSelection(elem); // 有选中区域则删除选中内容,否则删除光标前一个字符 if (selection.start !== selection.end) { elem.value = elem.value.slice(0, selection.start) + elem.value.slice(selection.end); elem.setSelectionRange(selection.start, selection.start); } else if (selection.start > 0) { elem.value = elem.value.slice(0, selection.start - 1) + elem.value.slice(selection.start); elem.setSelectionRange(selection.start - 1, selection.start - 1); } elem.focus(); } function moveBack(elId) { var elem = document.getElementById(elId); var currentStart = getInputSelection(elem).start; // 边界限制:不能小于0 var newPos = Math.max(currentStart - 1, 0); elem.setSelectionRange(newPos, newPos); elem.focus(); } function moveForward(elId) { var elem = document.getElementById(elId); var currentStart = getInputSelection(elem).start; var maxPos = elem.value.length; // 边界限制:不能超过内容长度 var newPos = Math.min(currentStart + 1, maxPos); elem.setSelectionRange(newPos, newPos); elem.focus(); } function insertChar(char) { var elem = document.getElementById('user'); var selection = getInputSelection(elem); // 在光标位置插入字符 elem.value = elem.value.slice(0, selection.start) + char + elem.value.slice(selection.end); // 将光标移到插入字符的下一位 elem.setSelectionRange(selection.start + 1, selection.start + 1); elem.focus(); } function setA(){ insertChar("A"); } function setB(){ insertChar("B"); } function setC(){ insertChar("C"); } function setD(){ insertChar("D"); }
HTML 代码
<input id="user" type="text"> <button type="button" onclick="setBack();">backspace</button> <button type="button" onclick="moveBack('user')">back</button> <button type="button" onclick="moveForward('user')">forward</button> <div> <button type="button" onclick="setA()">A</button> <button type="button" onclick="setB()">B</button> <button type="button" onclick="setC()">C</button> <button type="button" onclick="setD()">D</button> </div>
内容的提问来源于stack exchange,提问作者Jonny
相关产品推荐
相关产品推荐

