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知识点收藏
Feb 22 Javascript
json 入门基础教程 推荐
Oct 31 Javascript
防止文件缓存的js代码
Jan 10 Javascript
Jquery操作js数组及对象示例代码
May 11 Javascript
js的[defer]和[async]属性
Nov 24 Javascript
基于jQuery实现网页进度显示插件
Mar 04 Javascript
如何通过js实现图片预览功能【附实例代码】
Mar 30 Javascript
jQuery对象与DOM对象转换方法详解
May 10 Javascript
解决BootStrap Fileinput手机图片上传显示旋转问题
Jun 01 Javascript
js装饰设计模式学习心得
Feb 17 Javascript
Cordova(ionic)项目实现双击返回键退出应用
Sep 17 Javascript
JavaScript实现HTML导航栏下拉菜单
Nov 25 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
10条PHP编程习惯助你找工作
2008/09/29 PHP
PHP 压缩文件夹的类代码
2009/11/05 PHP
PHP错误Allowed memory size of 67108864 bytes exhausted的3种解决办法
2014/07/28 PHP
php简单中奖算法(实例)
2017/08/15 PHP
js 判断 enter 事件
2009/02/12 Javascript
WordPress 照片lightbox效果的运用几点
2009/06/22 Javascript
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(下:动画篇)
2010/03/24 Javascript
Jquery 切换不同图片示例代码
2013/12/05 Javascript
js使用eval解析json(js中使用json)
2014/01/17 Javascript
JS中判断null、undefined与NaN的方法
2014/03/26 Javascript
node.js实现逐行读取文件内容的代码
2014/06/27 Javascript
实现前后端数据交互方法汇总
2015/04/07 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
2015/08/07 Javascript
JS+CSS实现带有碰撞缓冲效果的竖向导航条代码
2015/09/15 Javascript
ionic App问题总结系列之ionic点击系统返回键退出App
2017/08/19 Javascript
vue中子组件调用兄弟组件方法
2018/07/06 Javascript
element-ui 关于获取select 的label值方法
2018/08/24 Javascript
vue发送ajax请求详解
2018/10/09 Javascript
微信小程序云开发之使用云数据库
2019/05/17 Javascript
JS实现百度搜索框关键字推荐
2020/02/17 Javascript
jQuery实现倒计时功能完整示例
2020/06/01 jQuery
vue界面发送表情的实现代码
2020/09/11 Javascript
浅谈Python黑帽子取代netcat
2018/02/10 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
2018/05/26 Python
OpenCV图像颜色反转算法详解
2019/05/13 Python
django实现HttpResponse返回json数据为中文
2020/03/27 Python
如何在windows下安装Pycham2020软件(方法步骤详解)
2020/05/03 Python
部署Django到阿里云服务器教程示例
2020/06/03 Python
keras自定义损失函数并且模型加载的写法介绍
2020/06/15 Python
基于Python采集爬取微信公众号历史数据
2020/11/27 Python
美国专注于健康商品的网站:eVitamins
2017/01/23 全球购物
打造完美自荐信
2014/01/24 职场文书
信息专业学生学习的自我评价
2014/02/17 职场文书
岗位说明书怎么写
2014/07/30 职场文书
会计专业2019暑假实习报告
2019/06/21 职场文书
Spring Boot 实现 WebSocket
2022/04/30 Java/Android