jQuery TodoList动态增删异常求助:元素错位与管道符问题
TodoList组件删除与新增功能问题修复
问题梳理
新增删除按钮后出现以下问题:
- 删除部分行后再新增,出现内容覆盖、显示顺序异常的情况
- 无法保证第一个
span.output前永远不显示管道符(|)
问题根源
- 删除逻辑错误:删除行时先移除了父元素
.flex-row,再尝试获取其中input的ID,此时父元素已脱离DOM,无法正确获取ID,导致对应的.output元素未被删除。最终.output数量与输入行数量不匹配,输入行的索引与.output的索引无法一一对应,引发内容覆盖。 - 索引判断依赖错误:管道符的判断依赖输入行在section所有子元素中的索引,若section中存在其他非输入行元素(如显示output的行),或删除行后索引动态变化,可能导致判断逻辑失效。
- 新增计数逻辑冗余:
count++的方式易与实际输入行数量脱节,删除行后计数无法同步更新。
修复方案
1. 修正删除逻辑
先获取要删除的input的ID,再移除父元素,最后删除对应的.output元素,确保输入行与.output数量始终一致。
2. 优化管道符判断
基于输入行在所有输入行中的相对位置判断是否添加管道符,避免其他元素干扰。
3. 简化新增计数逻辑
直接通过当前输入行的数量计算新增行的属性值,确保与实际数量同步。
修复后的完整代码
JavaScript代码
$(function() { // 输入内容同步到output $(".container").on('input', 'input[type=text]', function(event) { // 获取当前输入行在所有输入行中的索引 var inputRows = $(".container .flex-row:not(.output-row)"); var i = inputRows.index($(this).closest(".flex-row")); // 根据索引判断是否添加管道符 var v = (i === 0) ? $(this).val() : "|" + $(this).val(); // 找到对应的output元素并更新内容 $("#custom_wrapper .output").eq(i).html(v); }); // 新增行 $('.add').click(function() { var inputRows = $(".container .flex-row:not(.output-row)"); var count = inputRows.length + 1; // 插入到add按钮之前(所有输入行的末尾) var row = $("<div>", { class: "flex-row" }).insertBefore(this); $("<label>").appendTo(row); $("<input>", { type: "text", class: "input", id: "custom-text-" + count, placeholder: "custom text " + count, tabindex: count }).appendTo($("label", row)); $("<button>", { class: "remove" }).html("-").appendTo(row); // 新增对应的output元素 $("<span>", { class: "output", dataid: "custom-text-" + count }).insertAfter($("#custom_wrapper .output:last")); }); // 删除行 $('body').on('click', '.remove', function() { // 先获取input的ID var inputId = $(this).siblings('label').find('.input').attr("id"); // 移除当前输入行 $(this).parent('.flex-row').remove(); // 删除对应的output元素 $('#custom_wrapper .output[dataid="' + inputId + '"]').remove(); // 重新同步所有输入行的内容到output,确保管道符显示正确 $(".container .input").trigger('input'); }); })
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> <div class="container"> <div class="wrapper"> <article> <section> <div class="flex-row"> <label><input class="input" type="text" name="" id="custom-text-1" placeholder="custom text" tabindex="1" /></label><button class="remove">-</button> </div> <div class="flex-row"> <label><input class="input" type="text" name="" id="custom-text-2" placeholder="custom text 2" tabindex="2"></label><button class="remove">-</button> </div> <button class="add">+</button> <div class="flex-row output-row"> <div class="token">{{customText[<span id="custom_wrapper"><span class="output" dataid="custom-text-1"></span><span class="output" dataid="custom-text-2"></span></span>]}}</div> </div> </section> </article> </div> </div>
修复说明
- 给显示output的行添加了
.output-row类,方便区分输入行,确保索引计算仅针对输入行。 - 删除行时先获取input的ID,再执行删除操作,确保对应的
.output被同步移除。 - 删除后触发所有input的
input事件,重新同步内容,保证管道符显示正确。 - 新增行时直接通过当前输入行数量计算属性值,避免计数与实际数量不符。
内容的提问来源于stack exchange,提问作者blogob
相关产品推荐
相关产品推荐

