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的面向对象编程基础
Aug 13 Javascript
AngularJS基础 ng-mouseover 指令简单示例
Aug 02 Javascript
微信小程序(应用号)简单实例应用及实例详解
Sep 26 Javascript
纯JavaScript 实现flappy bird小游戏实例代码
Sep 27 Javascript
利用JQuery阻止事件冒泡
Dec 01 Javascript
jQuery设置和获取select、checkbox、radio的选中值方法
Jan 01 Javascript
ES6正则表达式扩展笔记
Jul 25 Javascript
Bootstrap实现翻页效果
Nov 27 Javascript
详解angular2.x创建项目入门指令
Oct 11 Javascript
JS高阶函数原理与用法实例分析
Jan 15 Javascript
详解jQuery设置内容和属性
Apr 11 jQuery
JQuery的加载和选择器用法简单示例
May 13 jQuery
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+ajax做仿百度搜索下拉自动提示框(有实例)
2012/08/21 PHP
浅析PHP 按位与或 (^ 、&amp;)
2013/06/21 PHP
PHP实现的QQ空间g_tk加密算法
2015/07/09 PHP
PHP的全局错误处理详解
2016/04/25 PHP
jQueryUI如何自定义组件实现代码
2010/11/14 Javascript
NodeJS框架Express的模板视图机制分析
2011/07/19 NodeJs
各浏览器对click方法的支持差异小结
2011/07/31 Javascript
javascript延时加载之defer测试
2012/12/28 Javascript
javascript中String对象的slice()方法分析
2014/12/20 Javascript
jQuery中的pushStack实现原理和应用实例
2015/02/03 Javascript
js格式化时间的简单实例
2016/11/27 Javascript
Vue数据驱动模拟实现4
2017/01/12 Javascript
JS+Ajax实现百度智能搜索框
2017/08/04 Javascript
vue router学习之动态路由和嵌套路由详解
2017/09/21 Javascript
vue实现的下拉框功能示例
2019/01/29 Javascript
vue-cli和v-charts实现可视化图表过程解析
2019/10/08 Javascript
Vue开发中遇到的跨域问题及解决方法
2020/02/11 Javascript
[02:52]2017DOTA2国际邀请赛中国区预选赛晋级之路
2017/07/03 DOTA
python函数返回多个值的示例方法
2013/12/04 Python
Python自动连接ssh的方法
2015/03/07 Python
Python中set与frozenset方法和区别详解
2016/05/23 Python
Python多线程爬虫实战_爬取糗事百科段子的实例
2017/12/15 Python
python实现一个简单RPC框架的示例
2020/10/28 Python
CSS3之边框多颜色Border-color属性使用示例
2013/10/11 HTML / CSS
Monnier Freres中文官网:法国领先的奢侈品配饰在线零售商
2017/11/01 全球购物
英国领先的在线旅游和休闲零售商:lastminute.com
2019/01/23 全球购物
英国历史最悠久的DJ设备供应商:DJ Finance、DJ Warehouse、The DJ Shop
2019/09/04 全球购物
一加手机美国官方网站:OnePlus美国
2019/09/19 全球购物
2014信息公开实施方案
2014/02/22 职场文书
会计个人实习计划书
2014/08/15 职场文书
文员转正自我鉴定怎么写
2014/09/29 职场文书
员工辞职信怎么写
2015/02/27 职场文书
CSS3新特性详解(五):多列columns column-count和flex布局
2021/04/30 HTML / CSS
如何制作自己的原生JavaScript路由
2021/05/05 Javascript
HTML+JS实现在线朗读器
2022/02/15 Javascript
redis数据结构之压缩列表
2022/03/21 Redis