代码如下: //灵感来自 //http://www.cnblogs.com/jkisjk/archive/2011/01/28/array_quickly_sortby.html var hasDuplicate = false; var sortBy = function(nodes){ var result = [], array = [], n = nodes.length, i = n, node; while(node = nodes[–n]){ (array[n] = new Number(~~node.sourceIndex))._ = node; } array.sort(fu
【JavaScript 节点排序详解】
在JavaScript中,对HTML或XML文档中的节点进行排序是一项常见的任务,特别是在处理DOM操作时。本节将探讨一种基于`sourceIndex`属性的排序方法,以及当该属性不可用时如何利用最近公共祖先(LCA)来实现节点排序。
我们来看给出的代码片段:
```javascript
var hasDuplicate = false;
var sortBy = function(nodes){
var result = [], array = [], n = nodes.length, i = n, node;
while(node = nodes[--n]){
(array[n] = new Number(~~node.sourceIndex))._ = node;
}
array.sort(function(a,b){
if(a === b) hasDuplicate = true;
return a - b ;
});
while( i ) result[--i] = array[i]._;
return result;
}
```
这段代码的核心思想是利用`sourceIndex`属性对节点进行排序。`sourceIndex`在某些浏览器中提供,它表示节点在文档中的位置。通过创建一个数组并将其元素设置为带有`sourceIndex`值的新Number对象,然后使用`sort()`函数按数值大小进行排序。如果在排序过程中发现有相同的`sourceIndex`值,`hasDuplicate`变量会被设置为`true`。
然而,不是所有浏览器都支持`sourceIndex`属性,特别是在IE中,XML文档中没有这个属性。在这种情况下,我们需要通过其他方式来实现节点排序。一种可能的方法是利用`parentNode`和`nextSibling`属性,但这种方法可能无法显著提高排序速度。
为了解决这个问题,我们可以采用更复杂的算法,例如利用最近公共祖先(LCA)。以下是一个示例实现:
```javascript
var tick = 0, hasDuplicate = false;
var Rage = {
getLCA: function(nodes){
// ...
},
getList: function(nodes, parent){
// ...
},
getLists: function(){
// ...
},
sortList: function(a, b){
// ...
},
// ...
};
```
这段代码中,`Rage`对象包含了一些辅助方法,如`getLCA`用于找到节点的最近公共祖先,`getList`获取节点到最近公共祖先的路径,`getLists`收集所有节点到最近公共祖先的路径,以及`sortList`对两个节点列表进行比较。这种方法虽然理论上有其优势,但在实际应用中可能不如预期,可能因为求解LCA的过程导致效率下降。
总结来说,JavaScript中的节点排序可以分为两种策略:依赖`sourceIndex`属性的简单排序和基于最近公共祖先的复杂排序。前者适用于支持`sourceIndex`的环境,后者则在不支持`sourceIndex`时提供备选方案。在选择排序方法时,应考虑性能、兼容性和实际需求。对于大型或复杂的DOM结构,优化排序算法以减少遍历和计算的时间是非常重要的。