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 常用到的增,删,改,查操作代码
Dec 28 Javascript
JQuery性能优化的几点建议
May 14 Javascript
Flow之一个新的Javascript静态类型检查器
Dec 21 Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
Jan 19 Javascript
Vue实现双向数据绑定
May 03 Javascript
angular动态删除ng-repaeat添加的dom节点的方法
Jul 20 Javascript
基于DOM节点删除之empty和remove的区别(详解)
Sep 11 Javascript
浅谈vue,angular,react数据双向绑定原理分析
Nov 28 Javascript
深入理解js 中async 函数的含义和用法
May 13 Javascript
vue的toast弹窗组件实例详解
May 14 Javascript
vue基于Teleport实现Modal组件
May 31 Vue.js
JavaScript实现一键复制内容剪贴板
Jul 23 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如何解决网站大流量与高并发的问题
2011/06/25 PHP
关于svn冲突的解决方法
2013/06/21 PHP
thinkPHP多域名情况下使用memcache方式共享session数据的实现方法
2016/07/21 PHP
PHP中Laravel 关联查询返回错误id的解决方法
2017/04/01 PHP
prototype 1.5 &amp; scriptaculous 1.6.1 学习笔记
2006/09/07 Javascript
Javascript 表单之间的数据传递代码
2008/12/04 Javascript
Javascript typeof 用法
2008/12/28 Javascript
jquery子元素过滤选择器使用示例
2013/06/24 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
2013/12/26 Javascript
JS实现OCX控件的事件响应示例
2014/09/17 Javascript
JS实现仿FLASH效果的竖排导航代码
2015/09/15 Javascript
JS键盘版计算器的制作方法
2016/12/03 Javascript
JavaScript无操作后屏保功能的实现方法
2017/07/04 Javascript
vue通过点击事件读取音频文件的方法
2018/05/30 Javascript
Vue作用域插槽slot-scope实例代码
2018/09/05 Javascript
微信小程序局部刷新触发整页刷新效果的实现代码
2018/11/21 Javascript
小程序关于请求同步的总结
2019/05/05 Javascript
详解如何提升JSON.stringify()的性能
2019/06/12 Javascript
[57:31]DOTA2-DPC中国联赛 正赛 SAG vs CDEC BO3 第一场 2月1日
2021/03/11 DOTA
Python实现约瑟夫环问题的方法
2016/05/03 Python
Python multiprocess pool模块报错pickling error问题解决方法分析
2019/03/20 Python
纯CSS3实现手风琴风格菜单具体步骤
2013/05/06 HTML / CSS
10个最常见的HTML5面试题 附答案
2016/06/06 HTML / CSS
介绍一下Java的事务处理
2012/12/07 面试题
集体备课反思
2014/02/12 职场文书
教师评语大全
2014/04/28 职场文书
英语教师自荐信
2014/05/26 职场文书
药品营销策划方案
2014/06/15 职场文书
三关爱志愿服务活动方案
2014/08/17 职场文书
合作协议书范本
2014/10/25 职场文书
基层党员群众路线整改措施及努力方向
2014/10/28 职场文书
幼师辞职信范文
2015/02/27 职场文书
检讨书格式
2015/05/07 职场文书
不知如何爱孩子,这些方法教会您
2019/08/06 职场文书
pandas中DataFrame重置索引的几种方法
2021/05/24 Python
15个值得收藏的JavaScript函数
2021/09/15 Javascript