//Inspired by
//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(function(a,b){
if(a === b) hasDuplicate = true;
return a - b ;
});
while( i )
result[--i] = array[i]._;
return result;
}
But standard browsers do not support this attribute. In IE, XML documents do not have this attribute. In this case, it is necessary to follow the parentNode and nextSibling of the node. However, if you only compare them two by two, the speed cannot be improved. So we turned to comparing the order of children of the most recent common ancestor. At this time, the power of the algorithm is reflected. This is the first version, based on the LCA provided by a friend. Of course, the general idea is still attributed to JK. But the actual effect is not satisfactory, and it is slower than jQuery's sortOrder. It is estimated that the problem lies in the LCA.
//According to the ideas provided by JK here
/ /http://www.cnblogs.com/rubylouvre/archive/2011/01/28/1947286.html#2020900
var tick = 0, hasDuplicate = false;
var Rage = {
// form http://www.cnblogs.com/GrayZhang/archive/2010/12/29/find-closest-common-parent.html
getLCA:function(nodes){
var hash = {}, i = 0,
attr = "data-find" (tick),
length = nodes.length,
node,
parent,
counter = 0,
uuid;
while(node = nodes[i ]){
parent = node;
while(parent){
if(parent.nodeType === 1){
break;
}
uuid = parent.getAttribute(attr);
if(!uuid){
uuid = "_" ( counter);
parent.setAttribute(attr,uuid);
hash[uuid ] = {node:parent,count:1};
}else{
hash[uuid].count ;
}
parent = parent.parentNode;
}
}
for(var i in hash){
if(hash[i].count === length){
return hash[i].node;
}
}
} ,
getList: function(nodes,parent){//Get all ancestors from the current element to the nearest common ancestor, including itself
var list = [];
while(node){
if (node === parent){
break;
}
list.unshift(node);
node = node.parentNode;
}
return list;
} ,
getLists : function(){
var lists = [], getList = Rage.getList, i=0, node, list;
while(node = nodes[i ]){
list = getList(node,parent);
if(list.length){
lists[ lists.length ] = list;
}
}
return lists;
},
sortList : function(a,b){
var n = Math.min(a.length,b.length),ap,bp;
for(var i=0; i < n; i ){
ap = a[i],bp = b[i]
if(ap !== bp){
while(ap = ap.nextSibling){
if(ap == = bp){
return -1
}
}
return 1
}
}
return a.length-b.length;
},
uniqueSort : function(nodes){
var length = nodes.length;
var LCA = Rage.getLCA(nodes);
var lists = Rage.getLists(nodes,LCA);
lists .sort(Rage.sortList);
var list, i = 0, result = [];
while(list = lists[i ]){
result[result.length] list.pop() ;
}
if(result.length !== length){
result.unshift(LAC);
if(result.length != length){
hasDuplicate = true;
}
}
return result;
}
}
The following is the second version. After improvements, it is finally three times faster than the jQuery one (test The object is a document with more than 260 nodes)
var hasDuplicate = false;
var Rage = {
getList : function(node){
var list = [];
while(node){
if(node.nodeType === 9){
break;
}
list.unshift(node);
node = node.parentNode;
}
返回列表;
},
getLists : function(nodes){
varlists = [], getList = Rage.getList, i=0, 节点;
while(node =nodes[i]){
lists[lists.length] = getList(node);
}
返回列表;
},
sliceList : function(lists,num){
var result = [], i = 0, list;
while(list = strings[i ]){
list = list.slice(num);
if(list.length){
结果[ result.length ] = list;
}
}
返回结果;
},
sortList : function(a,b){
var n = Math.min(a.length,b.length),ap,bp;
for(var i=0; i ap = a[i],bp = b[i]
if(ap !== bp){
while (ap = ap.nextSibling){
if(ap === bp){
返回 -1
}
}
返回 1
}
}
返回a.length-b.length;
},
uniqueSort : function(nodes){
var length = Nodes.length;
var 列表 = Rage.getLists(nodes);
lists.sort(function(a,b){
return a.length - b.length;
});
var 深度 = 列表[0].length, 长度 = 列表.length, 父级, 剪切, ii = 0;
for(var i =0; i parent = 列表[0][i];
切=真;
for(var j = 1;j if(parent !==lists[j][i]){
cut = false;
休息;
}
}
if(cut){
ii
}else{
中断;
}
}
var LCA = 列表[0][ii-1];
lists = Rage.sliceList(lists,ii);
lists.sort(Rage.sortList);
var 列表,i = 0,结果 = [];
while(list = strings[i ]){
结果[result.length] = list.pop();
}
if(result.length !== length){
result.unshift(LCA);
if(result.length != length){
hasDuplicate = true;
}
}
返回结果;
}
}