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

如何让JavaScript增减按钮函数稳定运行?解决Uncaught TypeError报错

问题:自定义加减按钮偶尔失效,抛出Uncaught TypeError: Cannot read properties of null (reading 'value')

我正在创建两个带自定义「+」「-」按钮的数值输入框,但按钮功能仅偶尔生效,多数时候会抛出上述错误。

HTML代码

<div class="col">
    <div class="row">
        <div class="input-group mx-auto w-50">
            <div class="input-group-prepend">
                <button class="btn btn-dark btn-sm minus" data-id="one"
                    type="button"><i class="fa fa-minus"></i></button>
            </div>
            <input type="number" id="one" 
                class="form-control form-control-sm text-center" value="0">
            <div class="input-group-prepend">
                <button class="btn btn-dark btn-sm plus" data-id="one" type="button"><i
                        class="fa fa-plus"></i></button>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="input-group mx-auto w-50">
            <div class="input-group-prepend">
                <button class="btn btn-dark btn-sm minus" data-id="two"
                    type="button"><i class="fa fa-minus"></i></button>
            </div>
            <input type="number" id="two"
                class="form-control form-control-sm text-center" value="0">
            <div class="input-group-prepend">
                <button class="btn btn-dark btn-sm plus" data-id="two" type="button"><i
                        class="fa fa-plus"></i></button>
            </div>
        </div>
    </div>
</div>

JavaScript代码

<script>
document.addEventListener("DOMContentLoaded", () => {
    document.querySelectorAll('.minus').forEach(item => {
        item.addEventListener('click', event => {
            var input_id = event.target.getAttribute('data-id')
            console.log('Minus button clicked for input ' + input_id)
            var quantityInput = document.getElementById(input_id);
            var currentQuantity = parseInt(quantityInput.value);
            quantityInput.value = currentQuantity - 1
        })
    })
    document.querySelectorAll('.plus').forEach(item => {
        item.addEventListener('click', event => {
            var input_id = event.target.getAttribute('data-id')
            console.log('Plus button clicked for input ' + input_id)
            var quantityInput = document.getElementById(input_id);
            var currentQuantity = parseInt(quantityInput.value);
            quantityInput.value = currentQuantity + 1
        })
    })
})
</script>

错误原因

问题出在event.target上:按钮内部嵌套了<i>图标标签,当点击图标时,event.target指向的是<i>元素而非按钮本身——这个<i>元素没有data-id属性,导致input_id为null,进而document.getElementById(input_id)返回null,读取value时就会触发报错。只有点击按钮的空白区域(未点到图标)时,event.target才是按钮元素,功能才能正常运行。

解决方法

方案1:用event.currentTarget替代event.target

currentTarget始终指向绑定事件监听的元素(即按钮本身),不受点击子元素的影响:

document.addEventListener("DOMContentLoaded", () => {
    document.querySelectorAll('.minus').forEach(item => {
        item.addEventListener('click', event => {
            const input_id = event.currentTarget.getAttribute('data-id')
            console.log('Minus button clicked for input ' + input_id)
            const quantityInput = document.getElementById(input_id);
            const currentQuantity = parseInt(quantityInput.value);
            quantityInput.value = currentQuantity - 1
        })
    })
    document.querySelectorAll('.plus').forEach(item => {
        item.addEventListener('click', event => {
            const input_id = event.currentTarget.getAttribute('data-id')
            console.log('Plus button clicked for input ' + input_id)
            const quantityInput = document.getElementById(input_id);
            const currentQuantity = parseInt(quantityInput.value);
            quantityInput.value = currentQuantity + 1
        })
    })
})

方案2:直接通过按钮元素获取data-id

因为事件监听绑定在按钮上,直接用循环中的item(即按钮元素)获取data-id,无需依赖事件对象:

document.addEventListener("DOMContentLoaded", () => {
    document.querySelectorAll('.minus').forEach(item => {
        item.addEventListener('click', () => {
            const input_id = item.getAttribute('data-id')
            console.log('Minus button clicked for input ' + input_id)
            const quantityInput = document.getElementById(input_id);
            const currentQuantity = parseInt(quantityInput.value);
            quantityInput.value = currentQuantity - 1
        })
    })
    document.querySelectorAll('.plus').forEach(item => {
        item.addEventListener('click', () => {
            const input_id = item.getAttribute('data-id')
            console.log('Plus button clicked for input ' + input_id)
            const quantityInput = document.getElementById(input_id);
            const currentQuantity = parseInt(quantityInput.value);
            quantityInput.value = currentQuantity + 1
        })
    })
})

可选优化:限制数值边界

可以给输入值设置下限(比如不能小于0),避免出现负数:

// 以减号按钮为例,替换原赋值语句
quantityInput.value = Math.max(currentQuantity - 1, 0);

内容的提问来源于stack exchange,提问作者Shamil Jamion

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:36:23