HTML表格行缺少由CSS类绑定的事件监听器

前端开发 2026-07-09

我有一个HTML表格,想让用户能够添加行。把HTML重新格式化得更美观之后,当他们通过从模板行复制来添加一行时,新行上的CSS类绑定的事件监听器就不再起作用了。

请注意,模板行现在来自一个独立的表格(为了让HTML看起来更整洁)。我到底哪里做错了?

例如:

<table id='template' class='financial'>
<tr id='template-row'><td class='updateable'></td></tr>...
<!-- ... -->
</table>
<table id='table-for-adding-rows>
 <tr id='original-row'><td class='updateable'></td></tr>
 <!-- this row was copied from 'template-row' -->
 <tr id='added-row-1'><td class='updateable'></td></tr>
<!-- ... -->
$('.financial .updateable').change(function() {   modifyItem(this);  });

modifyItem() 在“table-for-adding-rows”中的原始行上被调用,但对从表格“template”添加的行并未调用。

解决方案

首先,需要对术语做一个小小的纠正。你贴出的CSS实际上是JavaScript,尽管 jQuery API使用CSS选择器 来定位元素。


jQuery并没有忘记事件处理程序。在 $(string).change(function) 被调用时,jQuery会直接把事件处理程序附加到匹配CSS选择器的元素上。对文档结构以任何方式进行修改后,新增的行上就不会再有这些事件处理程序。你需要逐一添加它们、在现有表格中克隆一行,或者使用事件代理,这可以通过 $.on(string) 函数实现。

使用 $.clone 来追加新行

<table id='table-for-adding-rows' class='financial'>
  <tr id='template' style='display: none'>
    <td class='updateable'></td>
  </tr>
  <tr id='original-row'>
    <td class='updateable'>...</td>
  </tr>
</table>

你需要在你正在修改的表格中放置模板行。接下来,在用于添加新行的代码中,克隆模板行:

let newRow = $('#template').clone(true);
let table = $('#table-for-adding-rows');

table.append(newRow);

请注意,.clone(true) 是你要的重载方式,这样jQuery也会克隆事件处理程序。

使用 $.on() 来追加新行(例如事件代理)

我偏好的做法是使用 事件代理;也就是把 “change” 处理程序挂到一个祖先元素上,该祖先元素会对来自子元素的冒泡事件做出响应。在这种情况下,把 “change” 处理程序挂到 <table> 元素上。$.on() 函数让这一步变得相当简单,因为它本质上会对匹配选择器的元素进行事件过滤。既然你想监听 .updateable 元素上的change事件,请按下面这样修改你的JavaScript:

$('#table-for-adding-rows').on('change', '.updateable', event => modifyItem(this));

你很可能需要把 modifyItem 函数改为使用 event.currentTarget 来引用被更改的元素。

备选方案

我看到有多人建议使用事件代理,你可以将它用于多个容器,例如

let elements = $(yourselectorhere);
for (let item of $('#table-for-adding-rows')) {
    $(item).on('change', '.updateable', function() {
        modifyItem(this);
    });
}

所以如果你拥有#table1、#table2、#table3,那么这将是你的选择器。另一种做法是这样:

function initializeUpdateable(context) {
    let innerContext = context.find(".updatetable:not(.initialized)");
    innerContext.change(function() {
        modifyItem(this);
    });
    innerContext.addClass("initialized");
}

并在需要添加新项时对 context 调用它。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章