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学习笔记之五 一个小细节renderTo和applyTo的区别
Jan 07 Javascript
由JavaScript技术实现的web小游戏(不含网游)
Jun 12 Javascript
jQuery中scrollTop()方法用法实例
Jan 16 Javascript
深入理解JavaScript中的对象
Jun 04 Javascript
jquery获取复选框checkbox的值的简单实现方法
May 26 Javascript
Ionic2系列之使用DeepLinker实现指定页面URL
Nov 21 Javascript
关于vuex的学习实践笔记
Apr 05 Javascript
js数组去重的N种方法(小结)
Jun 07 Javascript
Node.js如何对SQLite的async/await封装详解
Feb 14 Javascript
微信小程序wx.navigateTo中events属性实现页面间通信传值,数据同步
Jul 13 Javascript
node.js实现简单的压缩/解压缩功能示例
Nov 05 Javascript
vue 保留两位小数 不能直接用toFixed(2) 的解决
Aug 07 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的中问验证码
2006/11/25 PHP
利用Ffmpeg获得flv视频缩略图和视频时间的代码
2011/09/15 PHP
PHP中使用BigMap实例
2015/03/30 PHP
PHP基于Redis消息队列实现发布微博的方法
2017/05/03 PHP
php实现查询功能(数据访问)
2017/05/23 PHP
PHP实现网站应用微信登录功能详解
2019/04/11 PHP
xml文档转换工具,附图表例子(hta)
2010/11/17 Javascript
关于js遍历表格的实例
2013/07/10 Javascript
jQuery插件开发详细教程
2014/06/06 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
JS实现超过长度限制后自动跳转下一款文本框的方法
2015/02/23 Javascript
jquery表单验证插件(jquery.validate.js)的3种使用方式
2015/03/28 Javascript
css如何让浮动元素水平居中
2015/08/07 Javascript
javascript中JSON.parse()与eval()解析json的区别
2016/05/19 Javascript
Jquery元素追加和删除的实现方法
2016/05/24 Javascript
jQuery插件fullPage.js实现全屏滚动效果
2016/12/02 Javascript
JS重载实现方法分析
2016/12/16 Javascript
详解jQuery中的DOM操作
2016/12/23 Javascript
在vue中使用css modules替代scroped的方法
2018/03/10 Javascript
webpack 打包压缩js和css的方法示例
2018/03/20 Javascript
element ui table(表格)实现点击一行展开功能
2018/12/04 Javascript
jQuery插件实现非常实用的tab栏切换功能【案例】
2019/02/18 jQuery
js的新生代垃圾回收知识点总结
2019/08/22 Javascript
vue keep-alive的简单总结
2021/01/25 Vue.js
利用python代码写的12306订票代码
2015/12/20 Python
python的set处理二维数组转一维数组的方法示例
2019/05/31 Python
Python 获取ftp服务器文件时间的方法
2019/07/02 Python
python按键按住不放持续响应的实例代码
2019/07/17 Python
Python将视频或者动态图gif逐帧保存为图片的方法
2019/09/10 Python
python实现文件分片上传的接口自动化
2020/11/19 Python
python绘制高斯曲线
2021/02/19 Python
学校门卫岗位职责
2014/03/16 职场文书
民族团结演讲稿范文
2014/08/27 职场文书
2015年全国科普日活动总结
2015/03/23 职场文书
2015年公共机构节能宣传周活动总结
2015/03/26 职场文书
运动会口号霸气押韵
2015/12/24 职场文书