You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
        })
解决方案

核心问题分析

  1. countDiscount()无返回值:原函数直接给输入框赋值,没有返回计算结果,调用countDiscount().toFixed(2)会报错(undefined没有toFixed方法)。
  2. 字符串运算问题:val()返回的是字符串,直接参与计算会导致非预期结果(比如字符串拼接而非数值运算)。
  3. 事件绑定格式错误:多个事件之间用逗号分隔会被识别为单个事件名,导致部分事件不触发。
  4. 未处理除数为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:57:02