添加多组问题与选项的jQuery异常:添加选项按钮消失
问题解决:添加问题时选项按钮消失的修复
问题描述
编写的jQuery代码预期实现两个功能:
- 添加问题:克隆完整的问题模块(含问题输入框+选项模块)
- 添加选项:克隆完整的选项模块
但实际运行异常:点击「添加问题」按钮时,第一个问题的「添加选项」按钮会消失。
问题根源
- 重复ID冲突:DOM中ID必须唯一,但代码里多次使用
inputFormRow、question、select-options等同ID,导致选择器逻辑混乱,破坏原有元素布局。 - 容器定位错误:原代码将新问题模块追加到
#newRow(位于第一个「添加选项」按钮上方),插入后打乱了原按钮的DOM结构;添加选项的逻辑错误地指向全局容器#newQuestion,而非当前问题的选项容器。 - 事件绑定逻辑缺陷:未针对动态生成的元素做层级化事件绑定,导致新模块功能异常。
修正后的完整代码
HTML结构
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <label for="survey-name">Add Question below</label> <form method="post" action=""> <div class="row" id="questionsContainer"> <!-- 初始问题模块模板 --> <div class="col-lg-12 question-module"> <div class="form-group"> <label>Enter Question</label> <textarea class="form-control question-input" rows="3"></textarea> </div> <div class="options-container"> <div class="inputFormRow"> <div class="input-group mb-3"> <input type="text" name="options[]" class="form-control m-input" placeholder="Enter options" autocomplete="off"> <label> -OR - Select an option</label> <select class="form-control select-options"> <option value="0">Select an option</option> <option value="strongly-agree">Strongly Agree</option> <option value="agree">Agree</option> <option value="neither-agree-nor-disagree">Neither Agree nor Disagree</option> <option value="disagree">Disagree</option> <option value="strongly-disagree">Strongly Disagree</option> <option value="not-applicable">Not Applicable</option> </select> <div class="input-group-append"> <button type="button" class="btn btn-danger removeRow">Remove</button> </div> </div> </div> </div> <button type="button" class="btn btn-info addOptions">Add Options</button><br> </div> </div> <button id="addRow" type="button" class="btn btn-info">Add Questions</button> </form>
jQuery逻辑
// 添加新问题模块 $("#addRow").click(function() { // 克隆第一个问题模块作为模板 const questionTemplate = $('.question-module').first().clone(); // 清空克隆模块的输入内容,避免继承原数据 questionTemplate.find('.question-input').val(''); questionTemplate.find('.options-container .inputFormRow:not(:first)').remove(); questionTemplate.find('input[name="options[]"]').val(''); questionTemplate.find('.select-options').val('0'); // 将新模块追加到统一的问题容器 $('#questionsContainer').append(questionTemplate); }); // 给当前问题添加选项 $(document).on('click', '.addOptions', function() { // 定位到当前问题的选项容器 const optionsContainer = $(this).closest('.question-module').find('.options-container'); // 克隆第一个选项行作为模板 const optionTemplate = optionsContainer.find('.inputFormRow').first().clone(); // 清空克隆选项的内容 optionTemplate.find('input[name="options[]"]').val(''); optionTemplate.find('.select-options').val('0'); // 追加到当前问题的选项容器中 optionsContainer.append(optionTemplate); }); // 删除选项行(保留至少一个选项) $(document).on('click', '.removeRow', function() { const $targetRow = $(this).closest('.inputFormRow'); const optionsCount = $targetRow.closest('.options-container').find('.inputFormRow').length; if (optionsCount > 1) { $targetRow.remove(); } });
核心修正说明
- 替换重复ID为类选择器:彻底解决ID冲突导致的DOM逻辑混乱问题。
- 重构DOM层级:用
#questionsContainer统一管理所有问题模块,每个问题用.question-module包裹,内部包含独立的选项容器,确保添加选项时仅操作当前问题的选项。 - 模板克隆替代HTML拼接:提升代码可维护性,同时自动清空克隆内容,避免数据继承。
- 动态事件绑定:针对
document绑定事件,确保新生成的按钮能正常触发逻辑。 - 添加防误删逻辑:每个问题至少保留一个选项,避免出现无选项的问题模块。
内容的提问来源于stack exchange,提问作者TSCAmerica.com
相关产品推荐
相关产品推荐

