如何为只读number类型input实现千位空格分隔并解决内容消失问题
问题根因
type="number" 类型的 <input> 仅支持合法数字作为 value 值,你调用格式化函数返回的带空格字符串不属于合法数字格式,浏览器会自动将不合法的 value 置为空,这就是数字超过3位、触发格式化加空格后内容全部消失的原因。
解决方案
方案1:修改input类型为text(只读场景最推荐)
你的input已经配置了readonly属性,不需要用户直接输入、也不需要用到number类型自带的数字键盘、上下箭头调整等原生特性时,直接修改type为text即可,直接将格式化后的带空格字符串赋值给value。
代码修改示例:
<input type="text" onChange={props.onInputChange} value={props.value ? priceFormatterSpace(props.value) : '0'} min={props.min} max={props.max} readOnly="readonly" />
注意:后续业务逻辑需要用到原始数值时,直接取未格式化的数字类型的
props.value即可,不需要从input的value中反向解析去掉空格。
方案2:保留type="number",用CSS伪元素展示格式化内容
如果需要保留number类型的原生能力(比如原生min/max校验、表单提交自动识别数字值等),可以用自定义属性存储格式化后的内容,通过CSS伪元素渲染展示,原生value依然存储纯数字避免被置空。
第一步添加CSS样式:
/* 给input添加自定义类名price-input */ .price-input { position: relative; color: transparent; /* 隐藏原生的纯数字内容 */ } .price-input::after { content: attr(data-formatted-price); position: absolute; left: 4px; top: 50%; transform: translateY(-50%); color: inherit; pointer-events: none; }
第二步修改input代码:
<input type="number" onChange={props.onInputChange} value={props.value ? props.value : 0} min={props.min} max={props.max} readOnly="readonly" class="price-input" data-formatted-price={props.value ? priceFormatterSpace(props.value) : '0'} />
如果用的是React框架,把上面的class改为className即可。
格式化函数优化
可以补充边界处理逻辑,避免非数字值传入时报错:
export const priceFormatterSpace = (price) => { if (price === null || price === undefined) return '0'; const num = Number(price); if (isNaN(num)) return '0'; return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); };
内容的提问来源于stack exchange,提问作者agoumi
相关产品推荐
相关产品推荐

