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 面向对象编程(2) 定义类
May 18 Javascript
window.showModalDialog参数传递中含有特殊字符的处理方法
Jun 06 Javascript
使用JS获取当前地理位置方法汇总
Dec 18 Javascript
jQuery中:visible选择器用法实例
Dec 30 Javascript
yarn与npm的命令行小结
Oct 20 Javascript
JS简单验证上传文件类型的方法
Apr 17 Javascript
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
Apr 20 Javascript
在vue项目中集成graphql(vue-ApolloClient)
Sep 08 Javascript
移动端吸顶fixbar的解决方案详解
Jul 17 Javascript
layui按条件隐藏表格列的实例
Sep 19 Javascript
从零使用TypeScript开发项目打包发布到npm
Feb 14 Javascript
Ajax实现异步加载数据
Nov 17 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 MVC模式在网站架构中的实现分析
2010/03/04 PHP
php array的学习笔记
2012/05/16 PHP
javascript appendChild,innerHTML,join性能比较代码
2009/08/29 Javascript
js实现身份证号码验证的简单实例
2014/02/19 Javascript
常用的jQuery前端技巧收集
2014/12/24 Javascript
jQuery插件Validate实现自定义校验结果样式
2016/01/18 Javascript
基于javascript实现句子翻牌网页版小游戏
2016/03/23 Javascript
使用Promise解决多层异步调用的简单学习心得
2016/05/17 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
浅谈JavaScript正则表达式-非捕获性分组
2017/03/08 Javascript
完美解决UI-Grid表格元素中多个空格显示为一个空格的问题
2017/04/25 Javascript
利用javascript如何随机生成一定位数的密码
2017/09/22 Javascript
详解Chai.js断言库API中文文档
2018/01/31 Javascript
jQuery获取随机颜色的实例代码
2018/05/21 jQuery
区别JavaScript函数声明与变量声明
2018/09/12 Javascript
vue2 中二级路由高亮问题及配置方法
2019/06/10 Javascript
vue项目部署到nginx/tomcat服务器的实现
2019/08/26 Javascript
vue.js 实现a标签href里添加参数
2019/11/12 Javascript
Vue中通过vue-router实现命名视图的问题
2020/04/23 Javascript
vue实现匀速轮播效果
2020/06/29 Javascript
js在HTML的三种引用方式详解
2020/08/29 Javascript
Python可跨平台实现获取按键的方法
2015/03/05 Python
Python常用爬虫代码总结方便查询
2019/02/25 Python
一个基于canvas的移动端图片编辑器的实现
2020/10/28 HTML / CSS
当当网官方旗舰店:中国图书销售夺金品牌
2018/04/02 全球购物
白俄罗斯女装和针织品网上商店:Presli.by
2019/10/13 全球购物
法雷奥SQA(electric)面试问题
2016/01/23 面试题
先进德育工作者事迹材料
2014/01/24 职场文书
《最后的姿势》教学反思
2014/02/27 职场文书
经典而简洁的婚礼主持词
2014/03/13 职场文书
我们的节日端午节活动总结
2015/02/11 职场文书
初中教师德育工作总结2015
2015/05/12 职场文书
2016年优秀共产党员先进事迹材料
2016/02/29 职场文书
2019年教师入党申请书
2019/06/27 职场文书
Vue Element UI自定义描述列表组件
2021/05/18 Vue.js
Python中requests做接口测试的方法
2021/05/30 Python