如何根据DOM中元素的先后顺序对关联ID的引用项数组进行排序
需求说明
现有存储页面元素ID的数组,未按元素在DOM/页面中的实际位置排序,需要将数组项按照对应元素在页面上的先后顺序重排。
示例数组:
[{ id:'first', type:'TEXT'},{id:'third',type:'DROPDOWN'},{id:'second',type:'TEXT'}]预期输出:
[{id:'first', type:'TEXT'},{id:'second',type:'TEXT'},{id:'third',type:'DROPDOWN'}]
实现方案
可以通过DOM原生提供的compareDocumentPosition方法实现,该方法可返回两个节点在文档中的位置关系,基于它实现排序逻辑即可:
// 原始待排序数组 const originArr = [{ id:'first', type:'TEXT'},{id:'third',type:'DROPDOWN'},{id:'second',type:'TEXT'}]; // 提前缓存DOM节点优化性能(可选,数组量级大时推荐) const elemCache = new Map(); originArr.forEach(item => { const elem = document.getElementById(item.id); if (elem) elemCache.set(item.id, elem); }); // 排序核心逻辑 const sortedArr = originArr.sort((a, b) => { const elemA = elemCache.get(a.id); const elemB = elemCache.get(b.id); // 处理节点不存在的边界情况,不存在的节点统一排到末尾 if (!elemA) return 1; if (!elemB) return -1; // 按文档先后顺序排序 return elemA.compareDocumentPosition(elemB) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1; });
注意事项
- 排序基于当前已渲染完成的DOM结构执行,若后续DOM发生动态变更,需要重新执行排序获取最新顺序
- 上述代码已增加节点不存在的边界处理,不存在对应元素的数组项会默认排到结果末尾,可根据业务需求调整规则
内容的提问来源于stack exchange,提问作者Shriram Salunkhe
相关产品推荐
相关产品推荐

