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 相关文章推荐
TFDN图片播放器 不错自动播放
Oct 03 Javascript
Extjs学习笔记之七 布局
Jan 08 Javascript
location.href语句与火狐不兼容的问题
Jul 04 Javascript
javascript数组的使用
Mar 28 Javascript
Js实现无刷新删除内容
Apr 29 Javascript
jQuery实现打开页面渐现效果示例
Jul 27 Javascript
vue-router 中router-view不能渲染的解决方法
May 23 Javascript
video.js 实现视频只能后退不能快进的思路详解
Aug 09 Javascript
Node.js 获取微信JS-SDK CONFIG的方法示例
May 21 Javascript
bootstrap+spring boot实现面包屑导航功能(前端代码)
Oct 09 Javascript
原生js实现下拉选项卡
Nov 27 Javascript
Vue.js中v-bind指令的用法介绍
Mar 13 Vue.js
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
详解WordPress开发中get_header()获取头部函数的用法
2016/01/08 PHP
yii框架无限极分类的实现方法
2017/04/08 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
2020/04/14 PHP
仿163填写邮件地址自动显示下拉(无优化)
2008/11/05 Javascript
javascript 打印内容方法小结
2009/11/04 Javascript
解析使用js判断只能输入数字、字母等验证的方法(总结)
2013/05/14 Javascript
关于js遍历表格的实例
2013/07/10 Javascript
JS获取几种URL地址的方法小结
2014/02/26 Javascript
js拖拽一些常见的思路方法整理
2014/03/19 Javascript
JavaScript字符串对象replace方法实例(用于字符串替换或正则替换)
2014/10/16 Javascript
JavaScript中length属性的使用方法
2015/06/05 Javascript
JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式)
2015/08/04 Javascript
用户代理字符串userAgent可实现的四个识别
2015/09/20 Javascript
js实现网页图片延时加载 提升网页打开速度
2016/01/26 Javascript
基于jquery实现ajax无刷新评论
2020/08/19 Javascript
Bootstrap如何创建表单
2016/10/21 Javascript
Html中 IFrame的用法及注意点
2016/12/22 Javascript
对比分析Django的Q查询及AngularJS的Datatables分页插件
2017/02/07 Javascript
vue-router的使用方法及含参数的配置方法
2018/11/13 Javascript
JS实现的全选、全不选及反选功能【案例】
2019/02/19 Javascript
vue中使用vue-pdf的方法详解
2020/09/05 Javascript
[06:53]2018DOTA2国际邀请赛寻真——为复仇而来的Newbee
2018/08/15 DOTA
python实现给微信公众号发送消息的方法
2017/06/30 Python
基于Python实现的微信好友数据分析
2018/02/26 Python
pandas表连接 索引上的合并方法
2018/06/08 Python
python面向对象入门教程之从代码复用开始(一)
2018/12/11 Python
python+opencv实现霍夫变换检测直线
2020/10/23 Python
Python 使用 Pillow 模块给图片添加文字水印的方法
2019/08/30 Python
python:批量统计xml中各类目标的数量案例
2020/03/10 Python
Django 实现 Websocket 广播、点对点发送消息的代码
2020/06/03 Python
Python爬虫之爬取淘女郎照片示例详解
2020/07/28 Python
HTML5 Video/Audio播放本地文件示例介绍
2013/11/18 HTML / CSS
Html5定位终极解决方案
2020/02/05 HTML / CSS
Original Penguin英国官方网站:美国著名休闲时装品牌
2016/10/30 全球购物
小爸爸观后感
2015/06/15 职场文书
世界各国短波电台对东亚播送时间频率表(SW)
2021/06/28 无线电