jQuery排序div内动态span出现重复、父元素丢失问题求解
问题定位
你的排序代码存在3个核心错误,直接导致DOM结构破坏、元素重复渲染:
- 选择器匹配目标错误:你使用的选择器
.bk_slot_div1 span > span匹配的是最内层带id的时间span,但实际DOM结构中每个时间span外层都包裹了一层无属性的父span。排序后你直接将内层span追加到根容器下,外层的父span壳子遗留在DOM中,原有的嵌套结构被完全破坏。 - sort比较函数返回值不符合规范:JavaScript原生排序方法的比较函数要求返回数字类型:第一个元素排在前面时返回负数,元素相等返回0,第二个元素排在前面返回正数。你写的比较逻辑
parseInt(elem1.id) > parseInt(elem2.id)返回的是布尔值true/false,会被隐式转换为1/0,无法正确判断元素的先后顺序,直接导致排序错乱、节点重复。 - 冗余的节点删除操作+重复ID问题:
appendTo方法本身就会将元素从原有DOM位置移动到目标位置,不需要先执行remove()再追加,多余的删除操作容易引发DOM引用异常;另外你动态追加元素时使用了和初始静态DOM完全相同的id(7、8),违反了DOM id全局唯一的规范,选择元素时会匹配到冗余节点,进一步加剧重复渲染问题。
修正后代码
排序时直接选中.bk_slot_div1的直接子元素(也就是每个时间项的外层包裹span),通过子元素的id做数值比较,直接将排序后的节点列表追加回容器即可,不需要额外删除操作:
const $container = $('.bk_slot_div1'); // 动态追加元素时务必保证id唯一,示例追加新id项避免重复 $container.append('<span><span class="bk_slot_div" style="padding: 6px 11px;background: #FFFFFF;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="9" t-att-data-slot_plans="13:30">13:30</span></span><span><span class="disabled disable_msg" style="padding: 6px 11px;background: #e9ecef;font-size: 14px;color: #555555;text-align: center;border: 1px solid #979797;border-radius: 4px;cursor: pointer" id="10" t-att-data-slot_plans="14:00">14:00</span></span>'); // 正确排序逻辑:选中容器直接子span(外层包裹元素)排序 $container.children('span').sort(function(elem1, elem2) { const id1 = parseInt($(elem1).children('span').prop('id')); const id2 = parseInt($(elem2).children('span').prop('id')); return id1 - id2; // 升序排序,需要降序改为 return id2 - id1 }).appendTo($container);
效果说明
修正后的代码会保留原有的span嵌套结构,按内层span的id数值从小到大排列所有时间项,不会出现元素丢失、重复渲染的问题。
内容的提问来源于stack exchange,提问作者user3162878
相关产品推荐
相关产品推荐

