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 学习笔记 element属性控制
Jul 23 Javascript
javascript执行环境及作用域详解
May 05 Javascript
ES6中参数的默认值语法介绍
May 03 Javascript
微信小程序开发之map地图实现教程
Jun 08 Javascript
jQuery实现简单日期格式化功能示例
Sep 19 jQuery
对于input 框限定输入值为浮点型的js代码
Sep 25 Javascript
学习JS中的DOM节点以及操作
Apr 30 Javascript
在 Vue 项目中引入 tinymce 富文本编辑器的完整代码
May 04 Javascript
Vue.set 全局操作简单示例
Sep 19 Javascript
vue表单验证之禁止input输入框输入空格
Dec 03 Vue.js
五句话帮你轻松搞定js原型链
Dec 09 Javascript
浅谈vue2的$refs在vue3组合式API中的替代方法
Apr 18 Vue.js
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
php5.2时间相差8小时
2007/01/15 PHP
ecshop 订单确认中显示省市地址信息的方法
2010/03/15 PHP
php利用cookie实现访问次数统计代码
2011/05/19 PHP
PHP下利用shell后台运行PHP脚本,并获取该脚本的Process ID的代码
2011/09/19 PHP
电子商务网站上的常用的js放大镜效果
2011/12/08 Javascript
javascipt:filter过滤介绍及使用
2014/09/10 Javascript
JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)
2014/10/17 Javascript
js中获取键盘事件的简单实现方法
2016/10/10 Javascript
微信小程序 底部导航栏目开发资料
2016/12/05 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
2016/12/26 Javascript
微信小程序实现顶部下拉菜单栏
2018/11/04 Javascript
浅谈JS的原型和继承
2019/05/08 Javascript
vue3.0 搭建项目总结(详细步骤)
2019/05/20 Javascript
layui实现三级联动效果
2019/07/26 Javascript
layui 关闭open弹出框 刷新table表格页面的方法
2019/09/16 Javascript
详解element-ui中表单验证的三种方式
2019/09/18 Javascript
解决vant中 tab栏遇到的坑 van-tabs
2020/11/04 Javascript
Python实现检测服务器是否可以ping通的2种方法
2015/01/01 Python
python实现批量下载新浪博客的方法
2015/06/15 Python
python开发之函数定义实例分析
2015/11/12 Python
python绘制铅球的运行轨迹代码分享
2017/11/14 Python
Python字符串逆序输出的实例讲解
2019/02/16 Python
Python中如何使用if语句处理列表实例代码
2019/02/24 Python
Python Matplotlib实现三维数据的散点图绘制
2019/03/19 Python
pytorch如何冻结某层参数的实现
2020/01/10 Python
澳大利亚领先的睡衣品牌:Peter Alexander
2016/08/16 全球购物
玩具反斗城西班牙网上商城:ToysRUs西班牙
2017/01/19 全球购物
大学系主任推荐信范文
2013/12/24 职场文书
寒假思想汇报
2014/01/10 职场文书
空乘英文求职信
2014/04/13 职场文书
小学生环保倡议书
2014/05/15 职场文书
党员个人党性分析材料
2014/12/18 职场文书
2015年全国爱眼日活动小结
2015/02/27 职场文书
2015年小班保育员工作总结
2015/05/27 职场文书
最新的离婚协议书范本!
2019/07/02 职场文书
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers