如何避免HTML输入框数字格式化时出现'NaN'提示
问题根因
原有逻辑未在数字解析前过滤无效字符,直接对含非数字内容的输入调用parseFloat时会返回NaN,后续执行toLocaleString就会在输入框展示NaN结果。之前尝试的isNaN校验未先清洗输入值,对混合字符、特殊字符的判断存在偏差,无法生效。
可直接运行的修复代码
$(document).ready(function() { let maximumFractionDigits = 2; var valueInput = $("#exampleInput"); const formatNumber = (value) => { // 先移除已有千分位逗号,再过滤所有非数字、非小数点的无效字符 let cleanValue = value.replace(/,/g, '').replace(/[^\d.]/g, ''); // 处理重复小数点的情况,仅保留第一个小数点 const dotIndex = cleanValue.indexOf('.'); if (dotIndex !== -1) { cleanValue = cleanValue.slice(0, dotIndex + 1) + cleanValue.slice(dotIndex + 1).replace(/\./g, ''); // 限制小数位数不超过设定值 if (maximumFractionDigits > 0) { const [intPart, decPart] = cleanValue.split('.'); cleanValue = intPart + '.' + decPart.slice(0, maximumFractionDigits); } } // 无有效内容时直接返回空,不强制填充0 if (!cleanValue || cleanValue === '.') return cleanValue; const num = parseFloat(cleanValue); return isNaN(num) ? '' : num.toLocaleString('en-US', { maximumFractionDigits }); } valueInput.on('input', function() { // 记录原始光标位置,避免格式化后光标跳转到末尾 const cursorPos = this.selectionStart; const oldValueLen = this.value.length; if (!this.value || (maximumFractionDigits && this.value.endsWith('.'))) { return } const formattedValue = formatNumber(this.value); $(this).val(formattedValue); // 格式化后修正光标位置 const newValueLen = formattedValue.length; this.setSelectionRange(cursorPos + (newValueLen - oldValueLen), cursorPos + (newValueLen - oldValueLen)); }); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <input id="exampleInput" class="form-control" aria-label="Grant Amount" type="text" placeholder="0" name="price" required="">
核心修复逻辑
- 前置字符过滤:所有非数字、非小数点的输入字符(包括日文、字母、特殊符号)会在格式化前被移除,不会出现在输入框中
- 异常输入兼容:自动过滤重复输入的小数点,自动截断超过2位的小数部分,符合美元金额输入规则
- 空值处理:无有效数字输入时返回空字符串,不会强制填充0,彻底规避NaN显示问题
- 交互优化:增加光标位置修正逻辑,解决格式化后光标自动跳转到输入末尾的体验问题
内容的提问来源于stack exchange,提问作者Cheknov
相关产品推荐
相关产品推荐

