javascript 节点排序 2


Posted in Javascript onJanuary 31, 2011
//灵感来自 
//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; 
}

但标准浏览器不支持这属性,在IE中,XML文档也没有此属性,这时就需要跟据节点的parentNode与nextSibling,但如果单单是两两比较,速度是提升不了的。因此我们就转而比较最近公共祖先的孩子们的顺序了。这时,算法的威力就体现出来了。这是第一版,根据某一朋友提供的LCA搞出来的东西,当然大体思路还是归功于JK大神。但实际效果不如意,比jQuery的那个sortOrder慢,估计问题出在求LCA上。
//根据这里JK提供的思路 
//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){//获取当前元素到最近公共祖先间的所有祖先,包括自己 
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; 
} 
}

下面是第二版,经过改进,终于比jQuery的那个快上三倍(测试对象为拥有260多个节点的文档)
var hasDuplicate = false; 
var Rage = { 
getList : function(node){ 
var list = []; 
while(node){ 
if(node.nodeType === 9){ 
break; 
} 
list.unshift(node); 
node = node.parentNode; 
} 
return list; 
}, 
getLists : function(nodes){ 
var lists = [], getList = Rage.getList, i=0, node; 
while(node = nodes[i++]){ 
lists[ lists.length ] = getList(node); 
} 
return lists; 
}, 
sliceList : function(lists,num){ 
var result = [], i = 0, list; 
while(list = lists[i++]){ 
list = list.slice(num); 
if(list.length){ 
result[ result.length ] = list; 
} 
} 
return result; 
}, 
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 lists = Rage.getLists(nodes); 
lists.sort(function(a,b){ 
return a.length - b.length; 
}); 
var depth = lists[0].length, length = lists.length, parent, cut, ii = 0; 
for(var i =0; i < depth; i++){ 
parent = lists[0][i]; 
cut = true; 
for(var j = 1;j < length; j++){ 
if(parent !== lists[j][i]){ 
cut = false; 
break; 
} 
} 
if(cut){ 
ii++ 
}else{ 
break; 
} 
} 
var LCA = lists[0][ii-1]; 
lists = Rage.sliceList(lists,ii); 
lists.sort(Rage.sortList); 
var list, i = 0, result = []; 
while(list = lists[i++]){ 
result[result.length] = list.pop(); 
} 
if(result.length !== length){ 
result.unshift(LCA); 
if(result.length != length){ 
hasDuplicate = true; 
} 
} 
return result; 
} 
}
Javascript 相关文章推荐
jQuery入门问答 整理的几个常见的初学者问题
Feb 22 Javascript
Javascript实现的鼠标经过时播放声音
May 18 Javascript
跟我学习javascript的函数和函数表达式
Nov 16 Javascript
学习JavaScript设计模式(封装)
Nov 26 Javascript
JS实现的相册图片左右滚动完整实例
Nov 23 Javascript
JS返回只包含数字类型的数组实例分析
Dec 16 Javascript
Vue手把手教你撸一个 beforeEnter 钩子函数
Apr 24 Javascript
解决vue中使用Axios调用接口时出现的ie数据处理问题
Aug 13 Javascript
JS二级菜单不同实现方法分析【4种方法】
Dec 21 Javascript
详解Vue底部导航栏组件
May 02 Javascript
记录vue做微信自定义分享的一些问题
Sep 12 Javascript
javascript实现画板功能
Apr 12 Javascript
js自定义事件代码说明
Jan 31 #Javascript
jQuery帮助之筛选查找 children([expr])
Jan 31 #Javascript
jQuery find和children方法使用
Jan 31 #Javascript
与jquery serializeArray()一起使用的函数,主要来方便提交表单
Jan 31 #Javascript
基于jQuery实现表格数据的动态添加与统计的代码
Jan 31 #Javascript
jquery键盘事件介绍
Jan 31 #Javascript
javascript代码加载优化方法
Jan 30 #Javascript
You might like
spl_autoload_register与autoload的区别详解
2013/06/03 PHP
php比较两个绝对时间的大小
2014/01/31 PHP
php中stream(流)的用法
2014/03/25 PHP
ThinkPHP5 验证器的具体使用
2018/05/31 PHP
很多人都是用下面的js刷新站IP和PV
2008/09/05 Javascript
基于jQuery实现下拉收缩(展开与折叠)特效
2012/12/25 Javascript
JavaScript生成二维码图片小结
2015/12/27 Javascript
底部悬浮通栏可以关闭广告位的实现方法
2016/06/01 Javascript
Javascript 实现计算器时间功能详解及实例(二)
2017/01/08 Javascript
浅析vue深复制
2018/01/29 Javascript
vue2 全局变量的设置方法
2018/03/09 Javascript
Vue 页面状态保持页面间数据传输的一种方法(推荐)
2018/11/01 Javascript
JavaScript中的垃圾回收与内存泄漏示例详解
2019/05/02 Javascript
浅谈element中InfiniteScroll按需引入的一点注意事项
2020/06/05 Javascript
解决vue动态下拉菜单 有数据未反应的问题
2020/08/06 Javascript
js实现3D旋转效果
2020/08/18 Javascript
Pyhthon中使用compileall模块编译源文件为pyc文件
2015/04/28 Python
Python 爬虫的工具列表大全
2016/01/31 Python
python3.6生成器yield用法实例分析
2019/08/23 Python
利用Python的sympy包求解一元三次方程示例
2019/11/22 Python
python判断链表是否有环的实例代码
2020/01/31 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
2020/02/26 Python
JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解
2020/03/19 Python
keras.layer.input()用法说明
2020/06/16 Python
如何查找网页漏洞
2016/06/22 面试题
实习自荐信
2013/10/13 职场文书
《云雀的心愿》教学反思
2014/02/25 职场文书
小学绿色学校申报材料
2014/08/23 职场文书
校园广播稿精选
2014/10/01 职场文书
2014年销售人员工作总结
2014/11/27 职场文书
2015出纳试用期工作总结
2014/12/12 职场文书
承德避暑山庄导游词
2015/02/03 职场文书
搞笑婚庆主持词
2015/06/29 职场文书
小程序教您怎样你零成本推广获取数万用户的方法
2019/07/30 职场文书
详解MySQL中的主键与事务
2021/05/27 MySQL
Java移除无效括号的方法实现
2021/08/07 Java/Android