JavaScript正则限制contenteditable单元格仅输入数字及最多两位小数
解决contenteditable单元格的数字输入限制问题
我来帮你搞定这个需求!你的现有代码只处理了移除非数字字符,但没考虑小数点的规则,咱们一步步调整,实现仅允许数字、一个小数点,且小数点后最多两位的输入限制。
问题分析
原代码里的/\D/g正则会把所有非数字字符(包括小数点)都删掉,这显然不符合你要允许一个小数点的需求,同时也没限制小数点后的位数,所以需要重新设计处理逻辑。
解决方案逻辑
我们需要分三步处理输入内容:
- 只保留数字和小数点,移除其他所有字符
- 确保整个内容里最多只有一个小数点
- 如果存在小数点,限制其后面最多只能有两位数字
- 额外处理光标位置,避免修改内容后光标跳转到开头,提升用户体验
完整实现代码
HTML
<table class="table"> <tbody> <tr> <td id="test1" contenteditable="true"></td> </tr> </tbody> </table>
CSS
#test1 { border: 1px solid gray; padding: 5px; width: 100px; }
JavaScript
function restrictInput(event) { const element = event.target; let content = element.textContent; // 1. 移除所有非数字和非小数点的字符 content = content.replace(/[^0-9.]/g, ''); // 2. 确保最多只有一个小数点 const dotCount = (content.match(/\./g) || []).length; if (dotCount > 1) { const firstDotIndex = content.indexOf('.'); // 保留第一个小数点,删除后续所有小数点 content = content.slice(0, firstDotIndex + 1) + content.slice(firstDotIndex + 1).replace(/\./g, ''); } // 3. 限制小数点后最多两位数字 const dotIndex = content.indexOf('.'); if (dotIndex !== -1) { const integerPart = content.slice(0, dotIndex + 1); const decimalPart = content.slice(dotIndex + 1).slice(0, 2); content = integerPart + decimalPart; } // 处理光标位置,避免修改内容后光标跳转到开头 const selection = window.getSelection(); let cursorOffset = 0; if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); cursorOffset = range.startOffset; // 如果光标在被删除的字符之后,调整偏移量 if (cursorOffset > content.length) { cursorOffset = content.length; } } // 更新单元格内容 element.textContent = content; // 恢复光标位置 if (element.firstChild) { const newRange = document.createRange(); newRange.setStart(element.firstChild, cursorOffset); newRange.collapse(true); selection.removeAllRanges(); selection.addRange(newRange); } } // 绑定输入事件 document.getElementById("test1").addEventListener("input", restrictInput);
验证效果
这段代码完全支持你列出的所有有效输入示例:
2、0.2、0.35.5、.224.55、6.46546545.55
同时会自动过滤非法输入:比如输入多个小数点会保留第一个,小数点后超过两位的部分会被截断,非数字/小数点的字符会直接被移除。
内容的提问来源于stack exchange,提问作者user348246
相关产品推荐
相关产品推荐

