toFixed在输入框keyup事件中失效,需将折扣值保留两位小数
问题:计算折扣时无法保留两位小数
我开发了一个包含Price(原价)、Buyer Price(买家价)、Discount(折扣)的表单,已实现输入Buyer Price时自动计算并更新Discount值的功能,但无法通过toFixed(2)方法让Discount值仅保留两位小数,当前计算出的Discount小数位数过多,请求解决。
HTML表单代码
<div class="row"> <div class="col-md-3"> <div class="mb-6"> <label class="form-label" for="price">Price <span class="text-danger">*</span></label> <div class="input-group"> <div class="input-group-append"> <span class="input-group-text">Rp</span> </div> <input type="number" min="0" name="price" class="form-control" id="price" value="{{ old('price') ?? $product->price }}" required> <div class="valid-feedback"> Looks good! </div> </div> <div class="text-danger"> <small>{{ $errors->first('price') }}</small> </div> </div> </div> <div class="col-md-2"> <div class="mb-3"> <label class="form-label" for="buyer_price">Buyer Price</label> <div class="input-group"> <div class="input-group-append"> <span class="input-group-text">Rp</span> </div> <input type="number" min="0" name="buyer_price" step="any" class="form-control" id="buyer_price" value="{{ old('buyer_price') ?? $product->buyer_price }}" required> </div> <div class="text-danger"> <small>{{ $errors->first('buyer_price') }}</small> </div> </div> </div> <div class="col-md-2"> <div class="mb-3"> <label class="form-label" for="discount">Discount</label> <div class="input-group mb-3"> <input type="number" min="0" max="100" step="0.01" name="discount" class="form-control w-75" id="discount" value="{{ old('discount') ?? $product->discount ?? 0 }}"> <div class="input-group-append"> <span class="input-group-text">%</span> </div> <small class="text-secondary">you can leave it blank if 0</small> </div> <div class="text-danger"> <small>{{ $errors->first('discount') }}</small> </div> </div> </div> </div>
JavaScript代码(原代码)
const discountInput = $('#discount') const buyerPriceInput = $('#buyer_price') const priceInput = $('#price') const countBuyerPrice = () => { let discountValue = discountInput.val() let discount = discountValue / 100 let priceValue = priceInput.val() let result = priceValue - (priceValue * discount) if (discountInput.val() === 0) { buyerPriceInput.val(priceValue) return } buyerPriceInput.val(result) } const countDiscount = () => { let priceValue = priceInput.val() let buyerValue = buyerPriceInput.val() if (discountInput.val() === 0) { buyerPriceInput.val(priceValue) return } discountInput.val((priceValue - buyerValue) / priceValue * 100) } discountInput.on('keyup, change, input', function () { countBuyerPrice() }) priceInput.on('keyup, change, input', function () { if (discountInput.val() === '') { countDiscount() } else { countBuyerPrice() } }) buyerPriceInput.on('keyup, change, input', function () { countDiscount().toFixed(2) })
解决方案
核心问题分析
countDiscount()无返回值:原函数直接给输入框赋值,没有返回计算结果,调用countDiscount().toFixed(2)会报错(undefined没有toFixed方法)。- 字符串运算问题:
val()返回的是字符串,直接参与计算会导致非预期结果(比如字符串拼接而非数值运算)。 - 事件绑定格式错误:多个事件之间用逗号分隔会被识别为单个事件名,导致部分事件不触发。
- 未处理除数为0:当原价为0时,计算折扣会出现除以0的错误。
修改后的完整JavaScript代码
const discountInput = $('#discount') const buyerPriceInput = $('#buyer_price') const priceInput = $('#price') const countBuyerPrice = () => { // 转为数值类型,默认0避免空值/非数值问题 let discountValue = Number(discountInput.val()) || 0; let discount = discountValue / 100; let priceValue = Number(priceInput.val()) || 0; let result = priceValue - (priceValue * discount); if (discountValue === 0) { buyerPriceInput.val(priceValue.toFixed(2)); return; } // 买家价也保留两位小数,提升体验 buyerPriceInput.val(result.toFixed(2)); } const countDiscount = () => { let priceValue = Number(priceInput.val()) || 0; let buyerValue = Number(buyerPriceInput.val()) || 0; // 处理原价为0的情况,避免除以0 if (priceValue === 0) { discountInput.val(0); return; } if (Number(discountInput.val()) === 0) { buyerPriceInput.val(priceValue.toFixed(2)); return; } // 计算折扣并保留两位小数后赋值 const discount = ((priceValue - buyerValue) / priceValue * 100).toFixed(2); discountInput.val(discount); } // 修复事件绑定格式:用空格分隔多个事件 discountInput.on('keyup change input', function () { countBuyerPrice(); }) priceInput.on('keyup change input', function () { if (discountInput.val() === '') { countDiscount(); } else { countBuyerPrice(); } }) buyerPriceInput.on('keyup change input', function () { countDiscount(); })
关键修改点说明
- 数值类型转换:所有输入值通过
Number()转为数值,并用|| 0处理空值或非数值情况,避免计算错误。 toFixed(2)的正确使用:在计算折扣的逻辑内部直接调用toFixed(2),将结果转为保留两位小数的字符串后赋值给输入框。- 修复事件绑定:将事件名间的逗号改为空格,确保所有触发事件都能生效。
- 异常处理:增加原价为0的判断,避免除以0导致的NaN结果。
- 统一格式:买家价也统一保留两位小数,保持表单数值格式一致。
内容的提问来源于stack exchange,提问作者Dava Eranda
相关产品推荐
相关产品推荐

