jQuery绑定.on()事件后DOM元素插入表格时事件丢失问题
解决动态创建按钮的点击事件丢失问题
我仔细看了你的代码,发现事件丢失的核心原因是你在绑定事件时,目标按钮还没有被添加到DOM中,导致jQuery选择器找不到对应的元素,自然无法成功绑定事件。
具体问题分析
在buildControls函数里,你原本的写法存在逻辑漏洞:
var restart = $(div).clone(true).css({...}) restart.attr("id", "restartButton"+jobID) $("#restartButton"+jobID).on('click', function() { submitCommand("requeue", jobID) })
这里的问题在于:你刚给restart这个jQuery对象设置了id,但它此时还只是内存中的对象,并没有被插入到DOM树里。这时候用$("#restartButton"+jobID)去查找元素,jQuery找不到任何匹配的节点,所以on('click')根本没有绑定到任何元素上。
修复方案
直接在创建的restart jQuery对象上绑定事件,而不是通过id选择器去查找。这样不管元素有没有加入DOM,事件都会绑定到这个对象上。修改后的buildControls函数如下:
function buildControls(jobID) { var div = document.createElement("div") var cont = $(div).clone() var restart = $(div).clone().css({ "display": "inline-block", "width": 20, "height": 20, "background-image": "url(img/refresh.png)", "background-size":"contain" }) restart.attr("id", "restartButton"+jobID) // 直接在restart对象上绑定点击事件 restart.on('click', function() { submitCommand("requeue", jobID) }) $(cont).append(restart) return cont }
额外优化建议
- 我去掉了不必要的
clone(true):因为你克隆的是刚创建的空div元素,没有任何事件或数据需要克隆,clone()就足够用了,能让代码更简洁。 - 如果后续需要频繁更新表格,推荐使用事件委托:把事件绑定到不会被销毁的父容器上,通过事件冒泡处理动态元素的点击,这样不需要每次重建表格都重新绑定事件。示例代码如下:
// 在页面初始化时绑定一次即可,无需每次重建表格重复绑定 $("#jobsPane").on('click', '[id^="restartButton"]', function() { // 从按钮id中提取jobID var jobID = this.id.replace('restartButton', '') submitCommand("requeue", jobID) })
这种方式更高效,尤其适合你这种每次清空重建表格的场景,只要父容器#jobsPane不被销毁,事件就一直有效。
内容的提问来源于stack exchange,提问作者Adalast
相关产品推荐
相关产品推荐

