动态创建的重复表单中答案增删函数仅首个生效问题求助
问题解决:动态表单的答案添加/删除函数仅对初始表单生效
核心问题原因
你当前的代码直接给页面加载时就存在的#add_more_fields、#remove_fields绑定了点击事件,但通过克隆生成的新表单里的这些元素是后续动态创建的,初始绑定的事件不会自动作用于它们。另外,克隆后出现了重复ID(比如多个#add_more_fields),这违反了DOM规范(ID必须唯一),也是导致事件失效的隐性原因。
你需要查阅的技术关键词
- 事件委托(Event Delegation)
- jQuery
.on()方法 - 动态DOM元素的事件绑定
this关键字的上下文指向
代码修改方案
第一步:修正HTML中的重复ID问题
把表单内的ID改为类名,避免重复:
<!-- 将原#survey_options改为类 --> <div class="survey_options"> <h6>... and here, type in the answer options (maximum of 8)</h6> <input type="text" name="survey_options[]" class="survey_options_input" size="50" placeholder="Answer 1"> <input type="text" name="survey_options[]" class="survey_options_input" size="50" placeholder="Answer 2"> <input type="text" name="survey_options[]" class="survey_options_input" size="50" placeholder="Answer 3"> </div> <!-- 将原#add_more_fields、#remove_fields改为类 --> <div class="controls"> <a href="#/" class="add_more_fields"><i class="fa fa-plus"></i> Add answer</a> <a href="#/" class="remove_fields"><i class="fa fa-minus"></i> Remove answer</a> <!-- 其他内容不变 --> </div>
第二步:用事件委托绑定动态元素的事件
替换你原有的原生JS事件绑定代码,改用jQuery的事件委托(因为你已经引入了jQuery):
// 删除原有的add_more_fields.onclick和remove_fields.onclick代码,替换为以下内容 $(document).on('click', '.add_more_fields', function(e) { e.preventDefault(); // 阻止a标签默认跳转行为 // 通过this找到当前按钮所属的问题块,再定位到对应的选项容器 var $surveyOptions = $(this).closest('.spms').find('.survey_options'); var optionCount = $surveyOptions.find('.survey_options_input').length; if (optionCount >= 8) { alert("最多8个选项!"); return; } var $newInput = $('<input>') .attr('type', 'text') .attr('name', 'survey_options[]') .attr('class', 'survey_options_input') .attr('size', 50) .attr('placeholder', 'Answer ' + (optionCount + 1)); $surveyOptions.append($newInput); }); $(document).on('click', '.remove_fields', function(e) { e.preventDefault(); var $surveyOptions = $(this).closest('.spms').find('.survey_options'); var $inputs = $surveyOptions.find('.survey_options_input'); // 保留至少2个选项,所以数量>=3时才允许删除 if ($inputs.length >= 3) { $inputs.last().remove(); } });
第三步:优化表单克隆逻辑(可选但推荐)
克隆表单时清空输入内容,避免携带初始表单的内容:
// 在你的克隆表单代码里,修改find(':input')的处理 clone.find(':input').val('').attr('id', function(i, val) { return val + count; });
关于this的说明
在事件委托的处理函数中,this指向的是当前被点击的按钮(比如.add_more_fields)。通过$(this).closest('.spms')可以向上查找到最近的问题块容器,这样就能精准操作当前问题对应的选项,而不会影响其他问题块的内容。
内容的提问来源于stack exchange,提问作者markcod
相关产品推荐
相关产品推荐

