jQuery不使用remove()与append()如何调整DOM元素排列顺序
jQuery中不使用remove()和append()能否实现元素排列顺序调整?
问题场景
实现搜索框功能时,搜索查询返回的结果按固定顺序排列,每条结果包含配图,初始全量搜索结果示例如下:
--1-- [img] Terst1 --2-- [img] Texast2 --3-- [img] Texast3 --4-- [img] kaTest3 --5-- [img] deTest3
按操作顺序复现异常:
- 输入搜索关键词 'te',返回结果正常:
--1-- [img] Terst1 --2-- [img] Texast2 --3-- [img] Texbst3
- 补充输入关键词为 'tex',返回结果正常:
--2-- [img] Texast2 --3-- [img] Texbst3
- 继续输入关键词为 'texb',再删除字符 'b' 退回到
tex搜索状态时,结果顺序出现错乱:
--3-- [img] Texbst3 --2-- [img] Texast2
核心需求
- 删除搜索字符触发结果重排时,不能对已渲染展示的元素执行重新
append()操作,该操作会导致已加载的图片重复加载 - 不依赖
remove()、append()方法,直接遍历现有元素调整位置,实现类似浏览器开发者工具元素检查面板中拖拽调整HTML元素DOM位置的效果,比如将序号3的元素移动到序号2元素下方 - 之前尝试获取元素序号值做对比,调用
after()和before()方法调整位置,未达到预期效果
可行方案
完全可以实现。jQuery提供的before()、after()、prepend()方法在传入已存在的DOM节点/jQuery对象时,只会执行节点移动操作,不会销毁重建节点,不会触发已加载资源的重新请求,符合需求。
实现思路
- 不要依赖元素当前的DOM位置识别条目,给每个搜索结果项绑定唯一不变的标识,比如将条目对应id存在
data-id属性上 - 每次拿到正确排序的结果id列表后,按顺序逐个将对应已存在的DOM节点移动到目标位置即可,全程不需要删除、重建、重新挂载节点
参考代码
假设搜索结果容器选择器为.search-result-wrap,每个搜索结果项选择器为.result-item,项上通过data-id存储条目的唯一标识:
/** * 按目标顺序重排搜索结果,不触发资源重新加载 * @param {Array<number|string>} targetSortedIds 正确顺序的条目id数组 */ function reorderSearchResults(targetSortedIds) { const $container = $('.search-result-wrap'); let $lastPositionedItem = null; targetSortedIds.forEach(itemId => { // 直接获取页面上已存在的对应条目节点,不创建新节点 const $currentItem = $container.find(`.result-item[data-id="${itemId}"]`); if (!$lastPositionedItem) { // 排序第一位的元素直接放到容器最顶部 $container.prepend($currentItem); } else { // 后续元素依次放到上一个排好位置的元素后面 $lastPositionedItem.after($currentItem); } $lastPositionedItem = $currentItem; }); }
之前调用
after()/before()未生效,通常是遍历顺序错误、锚点元素选取偏差导致的。按上述逻辑从排序第一位的元素开始依次锚定插入,即可保证顺序完全匹配目标列表。
效果说明
该方案的DOM操作逻辑和开发者工具面板拖拽移动节点的逻辑完全一致,仅调整DOM树中节点的位置关系,不会触发img等已加载资源的二次请求。
内容的提问来源于stack exchange,提问作者emrez
相关产品推荐
相关产品推荐

