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和CSS模拟超链接的用户单击事件的实现代码
May 23 Javascript
12种不宜使用的Javascript语法整理
Nov 04 Javascript
JavaScript控制table某列不显示的方法
Mar 16 Javascript
jQuery选择id属性带有点符号元素的方法
Mar 17 Javascript
jQuery仿天猫实现超炫的加入购物车
May 04 Javascript
JS实现消息来时让网页标题闪动效果的方法
Apr 20 Javascript
js实现的简单图片浮动效果完整实例
May 10 Javascript
使用jQuery监听扫码枪输入并禁止手动输入的实现方法(推荐)
Mar 21 jQuery
深入理解vue-loader如何使用
Jun 06 Javascript
详解Vue路由钩子及应用场景(小结)
Nov 07 Javascript
Vue响应式原理Observer、Dep、Watcher理解
Jun 06 Javascript
js实现盒子移动动画效果
Aug 09 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集成FCK的函数代码
2008/09/27 PHP
ci检测是ajax还是页面post提交数据的方法
2014/11/10 PHP
PHP向浏览器输出内容的4个函数总结
2014/11/17 PHP
Laravel中使用Queue的最基本操作教程
2017/12/27 PHP
通过继承IHttpHandle实现JS插件的组织与管理
2010/07/13 Javascript
jquery入门—选择器实现隔行变色实例代码
2013/01/04 Javascript
JavaScript匿名函数与委托使用示例
2014/07/22 Javascript
JavaScript插件化开发教程 (二)
2015/01/27 Javascript
js实现鼠标感应图片展示的方法
2015/02/27 Javascript
基于jQuery实现选取月份插件附源码下载
2015/12/28 Javascript
如何利用Promises编写更优雅的JavaScript代码
2016/05/17 Javascript
JS版微信6.0分享接口用法分析
2016/10/13 Javascript
js 原型对象和原型链理解
2017/02/09 Javascript
Iscrool下拉刷新功能实现方法(推荐)
2017/06/26 Javascript
vue增删改查的简单操作
2017/07/15 Javascript
vue input输入框模糊查询的示例代码
2018/05/22 Javascript
如何为你的JS项目添加智能提示与类型检查详解
2019/03/12 Javascript
Jquery Fade用法详解
2020/11/06 jQuery
[01:08]DOTA2“血战之命”预告片
2017/08/12 DOTA
使用Python的Twisted框架编写简单的网络客户端
2015/04/16 Python
tensorflow实现简单的卷积神经网络
2018/05/24 Python
Python3.5运算符操作实例详解
2019/04/25 Python
python 并发编程 非阻塞IO模型原理解析
2019/08/20 Python
HTML5 语音搜索(淘宝店语音搜素)
2013/01/03 HTML / CSS
软件测试工程师结构化面试题库
2016/11/23 面试题
农民工工资承诺书范文
2014/03/31 职场文书
感恩教育活动总结
2014/05/05 职场文书
放飞梦想演讲稿200字
2014/08/26 职场文书
委托证明书
2014/09/17 职场文书
2014年党员整改措施范文
2014/09/21 职场文书
2014银行领导班子四风对照检查材料思想汇报
2014/09/25 职场文书
中小学生学籍证明
2014/10/25 职场文书
Python绘制分类图的方法
2021/04/20 Python
MySQL面试题讲解之如何设置Hash索引
2021/11/01 MySQL
Python 避免字典和元组的多重嵌套问题
2022/07/15 Python