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 相关文章推荐
学习ExtJS fit布局使用说明
Oct 08 Javascript
如何确保JavaScript的执行顺序 之实战篇
Mar 03 Javascript
js如何判断不同系统的浏览器类型
Oct 28 Javascript
按下Enter焦点移至下一个控件的实现js代码
Dec 11 Javascript
JS中使用sort结合localeCompare实现中文排序实例
Jul 23 Javascript
Bootstrap中的fileinput 多图片上传及编辑功能
Sep 05 Javascript
js实现做通讯录的索引滑动显示效果和滑动显示锚点效果
Feb 18 Javascript
Three.js获取鼠标点击的三维坐标示例代码
Mar 24 Javascript
vue2 全局变量的设置方法
Mar 09 Javascript
示例vue 的keep-alive缓存功能的实现
Dec 13 Javascript
vue 移动端注入骨架屏的配置方法
Jun 25 Javascript
vue的$http的get请求要加上params操作
Nov 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
php网站地图生成类示例
2014/01/13 PHP
php中stdClass的用法分析
2015/02/27 PHP
PHP中Http协议post请求参数
2015/11/02 PHP
thinkPHP分组后模板无法加载问题解决方法
2016/07/12 PHP
CL vs ForZe BO5 第二场 2.13
2021/03/10 DOTA
用jquery来定位
2007/02/20 Javascript
jQuery EasyUI 的EasyLoader功能介绍
2010/09/12 Javascript
jquery的flexigrid无法显示数据提示获取到数据
2013/07/19 Javascript
ExtJS4中使用mixins实现多继承示例
2013/12/03 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
用js写的一个路由(简单实例)
2016/09/24 Javascript
JS生成和下载二维码的代码
2016/12/07 Javascript
使用Javascript判断浏览器终端设备(PC、IOS(iphone)、Android)
2017/01/04 Javascript
jquery表单验证实例仿Toast提示效果
2017/03/03 Javascript
vue封装第三方插件并发布到npm的方法
2017/09/25 Javascript
对vue中v-if的常见使用方法详解
2018/09/28 Javascript
vue数据操作之点击事件实现num加减功能示例
2019/01/19 Javascript
在NodeJs中使用node-schedule增加定时器任务的方法
2020/06/08 NodeJs
Vue使用axios引起的后台session不同操作
2020/08/14 Javascript
[01:32:22]DOTA2-DPC中国联赛 正赛 Ehome vs VG BO3 第一场 2月5日
2021/03/11 DOTA
Python可变参数*args和**kwargs用法实例小结
2018/04/27 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
python实现下载pop3邮件保存到本地
2018/06/19 Python
Python面向对象进阶学习
2019/05/21 Python
python判断文件夹内是否存在指定后缀文件的实例
2019/06/10 Python
python循环输出三角形图案的例子
2019/11/22 Python
django执行数据库查询之后实现返回的结果集转json
2020/03/31 Python
Html5 语法与规则简要概述
2014/07/29 HTML / CSS
巴西男士个人护理产品商店:SHOP4MEN
2017/08/07 全球购物
Ibood荷兰:互联网每日最佳在线优惠
2019/02/28 全球购物
升国旗仪式主持词
2014/03/19 职场文书
招标授权委托书样本
2014/09/23 职场文书
英语演讲开场白
2015/05/29 职场文书
2015秋季幼儿园开学通知
2015/07/16 职场文书
vue3获取当前路由地址
2022/02/18 Vue.js
Spring boot实现上传文件到本地服务器
2022/08/14 Java/Android