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 相关文章推荐
JAVASCRIPT keycode总结
Feb 04 Javascript
EASYUI TREEGRID异步加载数据实现方法
Aug 22 Javascript
jquery应该如何来设置改变按钮input的onclick事件
Dec 10 Javascript
控制页面按钮在后台执行期间不重复提交的JS方法
Jun 24 Javascript
jquery实现带二级菜单的导航示例
Apr 28 Javascript
jQuery scrollFix滚动定位插件
Apr 01 Javascript
深入理解JS中的Function.prototype.bind()方法
Oct 11 Javascript
任意Json转成无序列表的方法示例
Dec 09 Javascript
微信小程序 用户数据解密详细介绍
Jan 09 Javascript
浅谈React Native Flexbox布局(小结)
Jan 08 Javascript
vue 项目打包通过命令修改 vue-router 模式 修改 API 接口前缀
Jun 13 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
Jul 22 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
一个PHP日历程序
2006/12/06 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
2016/10/18 PHP
jQuery实现的网格线绘制方法
2016/06/20 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
2016/08/02 Javascript
浅析上传头像示例及其注意事项
2016/12/14 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
2017/07/22 jQuery
vue实现学生录入系统之添加删除功能
2018/07/11 Javascript
vue首次赋值不触发watch的解决方法
2018/09/11 Javascript
微信小程序的tab选项卡的实现效果
2019/05/15 Javascript
小程序分页实践之编写可复用分页组件
2019/07/18 Javascript
js仿京东放大镜效果
2020/08/09 Javascript
原生js 实现表单验证功能
2021/02/08 Javascript
[40:05]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[49:02]KG vs Infamous 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
解决python报错MemoryError的问题
2018/06/26 Python
使用GitHub和Python实现持续部署的方法
2019/05/09 Python
Django框架使用mysql视图操作示例
2019/05/15 Python
pytorch sampler对数据进行采样的实现
2019/12/31 Python
python 实现两个线程交替执行
2020/05/02 Python
Python 捕获代码中所有异常的方法
2020/08/03 Python
蔻驰意大利官网:COACH意大利
2019/01/16 全球购物
南京软件公司的.net程序员笔试题
2014/08/31 面试题
模具专业推荐信
2013/10/30 职场文书
大学毕业感言100字
2014/02/03 职场文书
大学毕业自我鉴定范文
2014/02/03 职场文书
带薪年假请假条
2014/02/04 职场文书
师范学院毕业生求职信
2014/06/24 职场文书
幼儿园秋季开学寄语
2014/08/02 职场文书
社区创先争优承诺书
2014/08/30 职场文书
红色旅游心得体会
2014/09/03 职场文书
委托证明模板
2014/09/16 职场文书
乡镇干部先进性教育活动个人整改措施
2014/09/16 职场文书
党的群众路线教育实践活动个人整改方案
2014/09/21 职场文书
2014预防青少年违法犯罪工作总结
2014/12/10 职场文书
护士业务学习心得体会
2016/01/25 职场文书
关于办理居住证的介绍信模板
2019/11/27 职场文书