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 相关文章推荐
jQuery 绑定事件到动态创建的元素上的方法实例
Aug 18 Javascript
图片放大镜jquery.jqzoom.js使用实例附放大镜图标
Jun 19 Javascript
使用不同的方法结合/合并两个JS数组
Sep 18 Javascript
jQuery使用$.ajax提交表单完整实例
Dec 11 Javascript
leaflet的开发入门教程
Nov 17 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
Jul 04 Javascript
echarts学习笔记之箱线图的分析与绘制详解
Nov 22 Javascript
jQuery封装animate.css的实例
Jan 04 jQuery
vue2.0使用swiper组件实现轮播的示例代码
Mar 03 Javascript
微信小程序仿RadioGroup改变样式的处理方案
Jul 13 Javascript
layui加载表格,绑定新增,编辑删除,查看按钮事件的例子
Sep 06 Javascript
使用JS来动态操作css的几种方法
Dec 18 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
[原创]CI(CodeIgniter)简单统计访问人数实现方法
2016/01/19 PHP
PHP第三方登录―QQ登录实现方法
2017/02/06 PHP
jquery制作搜狐快站页面效果示例分享
2014/02/21 Javascript
JavaScript调用ajax获取文本文件内容实现代码
2014/03/28 Javascript
jquery新的绑定事件机制on方法的使用方法
2014/04/15 Javascript
JS实现简单路由器功能的方法
2015/05/27 Javascript
javascript判断复选框是否选中的方法
2015/10/16 Javascript
javascript实现起伏的水波背景效果
2016/05/16 Javascript
vue.js中Vue-router 2.0基础实践教程
2017/05/08 Javascript
jQuery自定义多选下拉框效果
2017/06/19 jQuery
vue Render中slots的使用的实例代码
2017/07/19 Javascript
layer.open关闭父窗口 以及调用父页面的方法
2018/08/17 Javascript
React Native中Mobx的使用方法详解
2018/12/04 Javascript
JavaScript常用工具方法封装
2019/02/12 Javascript
JS实现鼠标移动拖尾
2020/12/27 Javascript
[42:32]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第二场 10.28
2020/10/28 DOTA
Python httplib,smtplib使用方法
2008/09/06 Python
Python实现Const详解
2015/01/27 Python
python实现的简单窗口倒计时界面实例
2015/05/05 Python
对Python中列表和数组的赋值,浅拷贝和深拷贝的实例讲解
2018/06/28 Python
django认证系统 Authentication使用详解
2019/07/22 Python
Python Flask上下文管理机制实例解析
2020/03/16 Python
浅谈JupyterNotebook导出pdf解决中文的问题
2020/04/22 Python
基于keras中的回调函数用法说明
2020/06/17 Python
Python使用socket_TCP实现小文件下载功能
2020/10/09 Python
ajax是什么及其工作原理
2012/02/08 面试题
通信工程专业女生个人求职信
2013/09/21 职场文书
2014年安全生产大检查方案
2014/05/13 职场文书
社会治安综合治理责任书
2015/01/29 职场文书
店长岗位职责
2015/02/11 职场文书
2015年政府采购工作总结
2015/05/21 职场文书
首次购房证明
2015/06/19 职场文书
2015七夕情人节宣传语
2015/07/14 职场文书
公司周年庆寄语
2019/06/21 职场文书
Vue实现tab导航栏并支持左右滑动功能
2021/06/28 Vue.js
java中用float时,数字后面加f,这样是为什么你知道吗
2021/09/04 Java/Android