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 读取和设置文档元素的样式属性
Apr 14 Javascript
jQuery select的操作实现代码
May 06 Javascript
jquery提交form表单时禁止重复提交的方法
Feb 13 Javascript
EasyUI中实现form表单提交的示例分享
Mar 01 Javascript
jQuery取得iframe中元素的常用方法详解
Jan 14 Javascript
JS读取XML文件数据并以table形式显示数据的方法(兼容IE与火狐)
Jun 02 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
Sep 17 Javascript
Bootstrap Table使用整理(五)之分页组合查询
Jun 09 Javascript
微信小程序 获取javascript 里的数据
Aug 17 Javascript
vue.js-div滚动条隐藏但有滚动效果的实现方法
Mar 03 Javascript
vue结合element-ui使用示例
Jan 24 Javascript
记录vue做微信自定义分享的一些问题
Sep 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
多重?l件?合查?(二)
2006/10/09 PHP
谈谈关于php的优点与缺点
2013/04/11 PHP
PHP APC的安装与使用详解
2013/06/13 PHP
PHP实现登录搜狐广告获取广告联盟数据的方法【附demo源码】
2016/10/14 PHP
php compact 通过变量创建数组
2016/11/15 PHP
django中的ajax组件教程详解
2018/10/18 PHP
PHP如何防止XSS攻击与XSS攻击原理的讲解
2019/03/22 PHP
javascript 清除输入框中的数据
2009/04/13 Javascript
基于JavaScript实现继承机制之原型链(prototype chaining)的详解
2013/05/07 Javascript
JS复制到剪贴板示例代码
2013/10/30 Javascript
控制文字内容的显示与隐藏示例
2014/06/11 Javascript
JavaScript数据类型检测代码分享
2015/01/26 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
2016/01/19 Javascript
JS 清除字符串数组中,重复元素的实现方法
2016/05/24 Javascript
深入浅出讲解ES6的解构
2016/08/03 Javascript
jQuery+ajax读取并解析XML文件的方法
2016/09/09 Javascript
JS jQuery使用正则表达式去空字符的简单实现代码
2017/05/20 jQuery
详解angular ui-grid之过滤器设置
2017/06/07 Javascript
Javascript实现base64的加密解密方法示例
2017/06/27 Javascript
vue.js声明式渲染和条件与循环基础知识
2017/07/31 Javascript
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
2019/06/18 jQuery
Vue组件简易模拟实现购物车
2020/12/21 Vue.js
[01:14:10]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Orenda
2014/05/22 DOTA
python 装饰器功能以及函数参数使用介绍
2012/01/27 Python
使用Python编写Linux系统守护进程实例
2015/02/03 Python
python调用matlab的m自定义函数方法
2019/02/18 Python
django 捕获异常和日志系统过程详解
2019/07/18 Python
Python流程控制语句的深入讲解
2020/06/15 Python
keras中的loss、optimizer、metrics用法
2020/06/15 Python
Selenium结合BeautifulSoup4编写简单的python爬虫
2020/11/06 Python
Deichmann英国:德国鞋类零售商
2021/01/30 全球购物
物理专业本科生自荐信
2014/01/30 职场文书
2013年最新自荐信范文
2014/06/23 职场文书
安全先进个人材料
2014/12/29 职场文书
机关保密工作承诺书
2015/05/04 职场文书
唱歌比赛拉拉队口号
2015/12/25 职场文书