动态添加DOM按钮绑定onclick报Uncaught TypeError解决方案
报错原因
页面初始加载执行JavaScript脚本时,id="button2"的按钮还未被插入DOM树,此时执行document.getElementById("button2")会返回null,对null值设置onclick属性就会抛出Uncaught TypeError: Cannot set properties of null (setting 'onclick')错误。
可行实现方案
方案1:插入元素后立刻绑定事件
把button2的事件绑定逻辑移动到button1的点击回调内部,确保执行绑定代码时button2已经被添加到DOM中,修改后的JS代码如下:
document.getElementById("button1").onclick = function () { let el = document.querySelector(".users"); // 先向DOM插入新按钮 el.innerHTML += `<button id="button2">LEGIT BUTTON</button>`; // 此时button2已存在,直接绑定事件不会报错 document.getElementById("button2").onclick = function(){ console.log("button2 is working!!!"); } }
方案2:使用事件委托(推荐动态元素场景使用)
利用事件冒泡机制,将事件绑定到页面加载时就已经存在的父级元素(本例中是class为users的div容器),通过判断事件触发的目标元素来执行对应逻辑,不需要等动态元素创建后再绑定,代码如下:
// 页面加载时即可直接给已存在的父容器绑定点击事件 document.querySelector(".users").addEventListener("click", function(e) { // 校验点击的目标是否为button2 if (e.target && e.target.id === "button2") { console.log("button2 is working!!!"); } }) // button1原有点击逻辑保持不变 document.getElementById("button1").onclick = function () { let el = document.querySelector(".users"); el.innerHTML += `<button id="button2">LEGIT BUTTON</button>`; }
- 该方案优势:后续如果需要新增更多动态生成的按钮,只需要在父容器的事件回调中新增对应目标判断即可,不需要每次插入元素都重复编写绑定逻辑,也不会出现找不到元素的空值报错。
注意:不建议把事件绑定逻辑放在
setTimeout之类的定时器里延迟执行,这种方式依赖定时时长,存在时序不稳定的问题,在DOM渲染慢的场景下依然可能报错。
内容的提问来源于stack exchange,提问作者BayernStrike
相关产品推荐
相关产品推荐

