jQuery动态添加文本框返回部分视图后点击添加按钮生成控件翻倍问题
问题核心根因
- 你当前给动态控件绑定的是jQuery委托事件,且直接把事件挂在了全局
body节点上。jQuery的.on()方法会在目标节点上叠加新的事件回调,不会自动覆盖已存在的同类型绑定。每次导航返回Question Bank部分视图时,页面会重新执行一遍对应JS逻辑,不断给body叠加重复的、逻辑完全相同的委托事件。 - 委托事件的触发规则是:事件冒泡到绑定节点后,会为每一套匹配的事件绑定执行一次回调。重复绑定N次,点击一次加号就会触发N次追加逻辑,自然出现点1次生成多个文本框的翻倍效果。
- 你之前尝试的
$("#txtOptions").empty()是操作DOM节点的清空逻辑,完全触碰不到已经挂在body上的重复事件,所以没有任何效果。
对应修复方案
改动最小的兼容方案:事件绑定前清理同命名空间的旧事件
给所有Question Bank模块的事件绑定加专属命名空间,每次执行JS绑定时,先把同命名空间的旧事件全部移除,从根源避免重复绑定。
改造后的参考代码:
// 所有绑定统一带qbModule命名空间,绑定前先清理同空间旧事件 // 处理Options列的加号事件 $('body').off('click.qbModule', '.addOptions') .on('click.qbModule', '.addOptions', function () { // 原有追加逻辑保持不变,仅把重复id改成类名避免DOM冲突 $(this).parent().append('<div class="dynamic-option-item"><input class="txtOptions form-control" name="" type="text" /></div><br />'); }); // 处理Answers列的加号事件 $('body').off('click.qbModule', '.addAnswers') .on('click.qbModule', '.addAnswers', function () { $(this).parent().append('<div class="dynamic-answer-item"><input class="txtAnswers form-control" type="text" /></div><br />'); }); // 给Add按钮的事件也加上同样的清理逻辑,避免重复绑定 $('#btnAdd').off('click.qbModule') .on('click.qbModule', function () { // 你原有的表格追加行逻辑完全保留即可 });
注意:绝对不要直接写
$('body').off('click'),这会把页面上其他业务的全局点击事件全部清掉,用专属命名空间可以精准只清理Question Bank模块绑定的事件,不会影响其他功能。
修正现有代码的隐藏DOM Bug
你原代码里动态追加元素时,给每个生成的容器都设置了id="txtOptions"、id="txtAnswers",这会导致页面出现大量重复ID,后续的DOM查找、清空操作永远只会命中第一个匹配的元素,完全失效。
- 必须把这些重复的ID全部替换成类名(就是上面参考代码里的
dynamic-option-item、dynamic-answer-item) - 后续如果需要清空所有动态生成的选项/答案文本框,用类选择器操作即可:
// 清空所有动态生成的选项项 $('.dynamic-option-item').remove() // 清空所有动态生成的答案项 $('.dynamic-answer-item').remove()
长期优化方案:缩小事件绑定的作用域
不要把所有委托事件都挂在全局body上,可以把绑定节点下移到表格的根元素#tblQuesAns上,缩小事件触发的判断范围,既提升性能,也避免事件污染全局:
// 直接在表格根节点上绑定委托事件 $('#tblQuesAns').off('click.qbModule', '.addOptions') .on('click.qbModule', '.addOptions', function() { // 原有追加逻辑 })
内容的提问来源于stack exchange,提问作者user8512043
相关产品推荐
相关产品推荐

