如何监听带contenteditable属性的td元素变更事件并新增表格行
问题根因
- contenteditable属性的元素不属于原生表单输入控件,没有内置的
change事件,所以直接绑定change事件不会触发,这是之前写法失效的核心原因。 - input事件是内容实时变化就触发,所以每输入/删除一个字符就执行,不符合需求。
实现方案
判断编辑完成的标准用两个触发条件二选一即可:
- 单元格失去焦点(blur事件):用户点击页面其他位置、结束编辑时触发
- 用户按下回车键:主动确认编辑完成时触发
同时可以加一层内容变更校验,避免用户未修改内容就误触发新增行的逻辑。
修改后代码
模板部分
<td contenteditable="true" class="num" (focus)="handleFocus($event)" (blur)="handleEditComplete($event)" (keydown.enter)="handleEditComplete($event)" > Editable Column Value 1 </td>
TS逻辑部分
// 存储单元格编辑前的原始值,用于判断是否真的修改了内容 private originValue: string = ''; // 单元格获得焦点时记录原始值 handleFocus(e: FocusEvent) { this.originValue = (e.target as HTMLElement).innerText.trim(); } // 编辑完成后执行的逻辑 handleEditComplete(e: Event) { const target = e.target as HTMLElement; const currentValue = target.innerText.trim(); // 只有内容确实发生了修改,才执行新增行逻辑 if (currentValue !== this.originValue) { const tblBody = document.getElementById('newTable').getElementsByTagName('tbody')[0]; const newNode = tblBody.rows[0].cloneNode(true); // 重置新行可编辑单元格的默认内容,避免和上一行重复 (newNode as HTMLElement).querySelector('.num').innerText = 'Editable Column Value 1'; tblBody.appendChild(newNode); // 更新原始值,避免下次编辑判断异常 this.originValue = currentValue; } // 如果是按回车键触发,要阻止默认的换行行为 if (e.type === 'keydown') { e.preventDefault(); // 按下回车后主动让单元格失去焦点,符合常规操作习惯 target.blur(); } }
注意事项
不要在click事件里反复绑定事件监听器,每次点击td都会新增一个事件绑定,多次点击后会重复执行逻辑,直接用Angular自带的事件绑定即可,不需要手动调用addEventListener或者用jQuery绑定事件。
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

