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

获取动态生成DOM元素并绑定点击事件报错的问题咨询

动态生成元素绑定点击事件失效的解决思路

问题描述

点击按钮触发函数生成表格内容,给表格内的<td>设置id="clickme"后尝试获取元素并绑定点击事件,触发报错:

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

问题原因

  1. 元素未生成时提前获取:页面加载时就执行document.querySelector('#clickme'),但此时<td>还未通过按钮点击生成,因此获取到null,绑定事件自然失败。
  2. 重复id违反规范:循环生成多个<td>都使用同一个id="clickme",HTML要求id必须唯一,这会导致后续元素的id无效,也不利于元素选择。

解决方法

方法一:事件委托(推荐)

利用事件冒泡机制,把点击事件绑定到已经存在的父元素(如表格的<tbody>)上,通过判断触发事件的目标元素来执行逻辑。同时将重复的id改为class,符合规范。

修改后的JavaScript代码:

const select = document.querySelector('#select')
const show = document.querySelector('#show')
const table = document.querySelector('#table')
const btn = document.querySelector('#send')
const arr = [{
    name: 'Mark',
    alter: 22,
}, {
    name: 'Emil',
    alter: 33,
}, {
    name: 'Sohab',
    alter: 64,
}, ]

btn.addEventListener('click', () => {
    table.innerHTML = ''
    arr.forEach((info) => {
        // 用class代替重复的id
        table.innerHTML += `
        <tr>
            <td class="clickme bg bg-info">${info.name}</td>
            <td>${info.alter}</td>
        </tr>
        `
    })
})

// 事件委托绑定到父元素table
table.addEventListener('click', (e) => {
    // 判断点击的是目标元素
    if (e.target.classList.contains('clickme')) {
        alert('TEST clickme')
    }
})

方法二:生成元素时直接绑定事件

不使用innerHTML拼接字符串,而是通过DOM API创建元素,在元素生成后立即绑定点击事件。

修改后的JavaScript代码:

const select = document.querySelector('#select')
const show = document.querySelector('#show')
const table = document.querySelector('#table')
const btn = document.querySelector('#send')
const arr = [{
    name: 'Mark',
    alter: 22,
}, {
    name: 'Emil',
    alter: 33,
}, {
    name: 'Sohab',
    alter: 64,
}, ]

btn.addEventListener('click', () => {
    table.innerHTML = ''
    arr.forEach((info) => {
        const tr = document.createElement('tr')
        
        const tdName = document.createElement('td')
        tdName.className = 'bg bg-info'
        tdName.textContent = info.name
        // 生成元素后直接绑定事件
        tdName.addEventListener('click', () => {
            alert('TEST clickme')
        })
        
        const tdAlter = document.createElement('td')
        tdAlter.textContent = info.alter
        
        tr.appendChild(tdName)
        tr.appendChild(tdAlter)
        table.appendChild(tr)
    })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:45:34