1.使用jquery,但没有遵循jquery编码风格,因为面向对象更易于维护,可扩展性更强。
2.节点DOM延迟生成。
3.可以通过节点生成前回调函数实现各种树形,满足大部分需求,只要你需要的是一个树形的展现形式。
5.节点删除,移动,添加兄弟节点/添加后代节点,均提供api,实现简单。
6.默认带有多选,单选模式,并可以组合使用。
7.打开节点可以用多种方式,甚至可以自编程。
8.已灵活性为诉求。
还有许多尚未完成的功能,因为项目中用不到,例如:异步加载.拖动排序.
希望大家多提建议!以让我改进。
DEMO和js文件均在附件中
谢谢lqixv兄,大家可以从 http://www.03soft.com/jQueryTree/ 预览效果。
1 楼
TonyBug
2011-02-12
挺不错的一个例子,目前正在学习jquery呢!对我的帮助很大,谢谢分享!
2 楼
fhx007
2011-02-14
例子很好,值得学习
3 楼
guoyingqiang
2011-02-14
谢谢。多多的
4 楼
lqixv
2011-02-14
为了方便大家看效果图,现在我把楼主的 demo 放到了这个地方,大家可以看看 demo:
http://www.03soft.com/jQueryTree/
http://www.03soft.com/jQueryTree/
5 楼
guoling09
2011-02-15
谢了,不错的教程!
6 楼
superobin
2011-02-15
var oriData = [ {myId:0,myParent:null,myTitle:'text0'}, {myId:1,myParent:0,myTitle:'text1'}, {myId:2,myParent:0,myTitle:'text2'}, {myId:3,myParent:1,myTitle:'text3'}, {myId:4,myParent:1,myTitle:'text4'}, {myId:5,myParent:3,myTitle:'text5'}, {myId:6,myParent:3,myTitle:'text6'}, {myId:7,myParent:4,myTitle:'text7'} ]; var scpt = document.createElement("script"); scpt.onload = scpt.onreadystatechange = function() { if(this.readyState && this.readyState.toLowerCase() != "loaded") { return; } jQuery.noConflict(); (function($) { function organizeTree(data,idKey,parentKey) { var tmp = {}; $(data).each(function() { tmp[this[idKey]]=this; }); var root; $(data).each(function () { if(this.__parentNode = tmp[this[parentKey]]) { (this.__parentNode.__childNodes||(this.__parentNode.__childNodes=[])).push(this); } else { root = this; } }); return root; } function createTree(data,offset,titleKey,prepend1,prepend2,prepend3) { offset = offset||20; titleKey = titleKey || 'title'; var tmp = $("<div>"); var children = data.__childNodes||[]; var text = (data[titleKey]||"").valueOf(); var titleLayer = $("<div>").appendTo(tmp).html(children.length?prepend1+text:prepend3+text) .css("cursor","pointer").attr("isTitle","true").css("line-height","20px"); var subLayer = $("<div>").css("margin-left",offset+"px").appendTo(tmp); $(children).each(function() { createTree(this,offset,titleKey,prepend1,prepend2,prepend3).appendTo(subLayer); }); if(children.length) { titleLayer.toggle(function() { titleLayer.html(prepend2+text); subLayer.hide("fast"); },function() { titleLayer.html(prepend1+text); subLayer.show("fast"); }); }; return tmp; } $(function() { var root = organizeTree(oriData,'myId','myParent'); createTree(root,20, 'myTitle',"<img src='http://www.destroydrop.com/javascripts/tree/example/img/folderopen.gif'/>", "<img src='http://www.destroydrop.com/javascripts/tree/example/img/folder.gif'/>","<img src='http://www.destroydrop.com/javascripts/tree/example/img/page.gif'/>" ).appendTo($("<div style='width:300px'></div>").appendTo(document.body)); }); })(jQuery); } scpt.src="http://code.jquery.com/jquery-1.5.min.js"; document.body.appendChild(scpt);
我贴个能立竿见影看到效果的,大家打开浏览器控制台,把上面代码贴进去执行即可(什么?没有控制台?IE8 F12,chrome ctrl+shift+j,如果还没有,那就算了)
如果chrome提示恶意网站,可能是因为图床的网站有问题,但是引用的图肯定没问题的。
7 楼
satanultra
2011-02-15
superobin 写道
var oriData = [ {myId:0,myParent:null,myTitle:'text0'}, {myId:1,myParent:0,myTitle:'text1'}, {myId:2,myParent:0,myTitle:'text2'}, {myId:3,myParent:1,myTitle:'text3'}, {myId:4,myParent:1,myTitle:'text4'}, {myId:5,myParent:3,myTitle:'text5'}, {myId:6,myParent:3,myTitle:'text6'}, {myId:7,myParent:4,myTitle:'text7'} ]; var scpt = document.createElement("script"); scpt.onload = scpt.onreadystatechange = function() { if(this.readyState && this.readyState.toLowerCase() != "loaded") { return; } jQuery.noConflict(); (function($) { function organizeTree(data,idKey,parentKey) { var tmp = {}; $(data).each(function() { tmp[this[idKey]]=this; }); var root; $(data).each(function () { if(this.__parentNode = tmp[this[parentKey]]) { (this.__parentNode.__childNodes||(this.__parentNode.__childNodes=[])).push(this); } else { root = this; } }); return root; } function createTree(data,offset,titleKey,prepend1,prepend2,prepend3) { offset = offset||20; titleKey = titleKey || 'title'; var tmp = $("<div>"); var children = data.__childNodes||[]; var text = (data[titleKey]||"").valueOf(); var titleLayer = $("<div>").appendTo(tmp).html(children.length?prepend1+text:prepend3+text) .css("cursor","pointer").attr("isTitle","true").css("line-height","20px"); var subLayer = $("<div>").css("margin-left",offset+"px").appendTo(tmp); $(children).each(function() { createTree(this,offset,titleKey,prepend1,prepend2,prepend3).appendTo(subLayer); }); if(children.length) { titleLayer.toggle(function() { titleLayer.html(prepend2+text); subLayer.hide("fast"); },function() { titleLayer.html(prepend1+text); subLayer.show("fast"); }); }; return tmp; } $(function() { var root = organizeTree(oriData,'myId','myParent'); createTree(root,20, 'myTitle',"<img src='http://www.destroydrop.com/javascripts/tree/example/img/folderopen.gif'/>", "<img src='http://www.destroydrop.com/javascripts/tree/example/img/folder.gif'/>","<img src='http://www.destroydrop.com/javascripts/tree/example/img/page.gif'/>" ).appendTo($("<div style='width:300px'></div>").appendTo(document.body)); }); })(jQuery); } scpt.src="http://code.jquery.com/jquery-1.5.min.js"; document.body.appendChild(scpt);
我贴个能立竿见影看到效果的,大家打开浏览器控制台,把上面代码贴进去执行即可(什么?没有控制台?IE8 F12,chrome ctrl+shift+j,如果还没有,那就算了)
如果chrome提示恶意网站,可能是因为图床的网站有问题,但是引用的图肯定没问题的。
还有这种方法!你真聪明!
8 楼
lqixv
2011-02-15
不错,下来看了一下,代码少而清晰!
为了方便大家看效果图,现在我把楼主的 demo 放到了这个地方,大家可以看看 demo:
http://www.03soft.com/jQueryTree/
为了方便大家看效果图,现在我把楼主的 demo 放到了这个地方,大家可以看看 demo:
http://www.03soft.com/jQueryTree/
9 楼
superobin
2011-02-15
恩,看到了,多谢楼上,看代码楼主的确下了功夫,注释和javadoc写的都不错。搞ui就是功夫活
另外问下楼上,这种空间哪儿能搞到。。。
另外问下楼上,这种空间哪儿能搞到。。。
10 楼
satanultra
2011-02-15
谢谢 lqixv 兄!
11 楼
lqixv
2011-02-16
superobin 写道
恩,看到了,多谢楼上,看代码楼主的确下了功夫,注释和javadoc写的都不错。搞ui就是功夫活
另外问下楼上,这种空间哪儿能搞到。。。
另外问下楼上,这种空间哪儿能搞到。。。
买的,空间只需要几十元,但只能支持 asp/.net/php
12 楼
emoshoushou
2011-05-05
satanultra大哥,我看了你例子,有点不明白。小弟新手,麻烦之处,请多多见谅!
1.如果不是例子上的数据源,该怎么处理呢比如一个list里放了多个对象,每个对象都有id,父id,name。
2. parent:parentid 树的父节点。parentid 是对象的父id对应的key么
3.我用json action传的数据,结果之出来树的根结点,其他的没出来是怎么回事
1.如果不是例子上的数据源,该怎么处理呢比如一个list里放了多个对象,每个对象都有id,父id,name。
2. parent:parentid 树的父节点。parentid 是对象的父id对应的key么
3.我用json action传的数据,结果之出来树的根结点,其他的没出来是怎么回事
13 楼
satanultra
2011-05-06
emoshoushou 写道
satanultra大哥,我看了你例子,有点不明白。小弟新手,麻烦之处,请多多见谅!
1.如果不是例子上的数据源,该怎么处理呢比如一个list里放了多个对象,每个对象都有id,父id,name。
2. parent:parentid 树的父节点。parentid 是对象的父id对应的key么
3.我用json action传的数据,结果之出来树的根结点,其他的没出来是怎么回事
1.如果不是例子上的数据源,该怎么处理呢比如一个list里放了多个对象,每个对象都有id,父id,name。
2. parent:parentid 树的父节点。parentid 是对象的父id对应的key么
3.我用json action传的数据,结果之出来树的根结点,其他的没出来是怎么回事
1,只要你给的数据源可遍历的(数组,list)就可以,唯一的麻烦可能是你对象的属性和我需要的不符合,这时候需要用到
treeEx4 = new $.Tree({ parent: parent, source: data, selectMode: "checkbox&single", pretreatment: function (node) { //因为这里传来的是一个数据对象引用,为了不破坏原有对象所以返回一个新对象,如果没有return,则默认用原始数据. return { id: "dataId" + node.id, //把"id"转换为"dataId_id" content: "<span class='tree-content'>-- " + node.content + " --</span>", //给内容外边加上一个span children: node.children }; } });
这里的pretreatment回调函数,这个函数的作用是每次生成节点前,都会把你当初给我的数据源中对应这个节点的相应的元素传递过来,因为我生成将节点需要"id"和"content"两个属性,"content"为必须既节点显示内容.所以你要用你数据结构中的相对应于这两个属性的属性组成一个新的对象return,树自然可以生成了。
2,parent是一个dom对象,不是id,是树在页面中的父元素。
3,这个不好说,最好让我看下源代码。
14 楼
emoshoushou
2011-05-06
首先,谢谢 satanultra大哥!!!还有点问题,想问问,呵呵
1.就是说把pretreatment: function (node){}方法里的id和content改为合适的id和name就可以了,对不对?
2.我想加一个点击事件,是应该加在哪呢,是onSelect吗?onSelect:function(node){var source = $(node).data("source"); getDeptUsersTreeQuery(source.id,source.content);}
3.parent: parent这是干什么的,是树在页面中的父元素,是树root节点的的DOM么。但具体是控制的,比如把parent改为别的,会出现什么效果?
4.pretreatment是控制source中data的输入么?
5.还有就是加一个双击事件怎么加,
大哥!麻烦那您了,小弟看您的插件,看不明白,不好意思,小弟是在太笨了,一点不会!!!!
1.就是说把pretreatment: function (node){}方法里的id和content改为合适的id和name就可以了,对不对?
2.我想加一个点击事件,是应该加在哪呢,是onSelect吗?onSelect:function(node){var source = $(node).data("source"); getDeptUsersTreeQuery(source.id,source.content);}
3.parent: parent这是干什么的,是树在页面中的父元素,是树root节点的的DOM么。但具体是控制的,比如把parent改为别的,会出现什么效果?
4.pretreatment是控制source中data的输入么?
5.还有就是加一个双击事件怎么加,
大哥!麻烦那您了,小弟看您的插件,看不明白,不好意思,小弟是在太笨了,一点不会!!!!
15 楼
satanultra
2011-05-06
1,是把相应的属性改为 id和content
2,对
3,对
4,它主要是为了适应不同的json格式,如果你按照我的json结构,那基本可以不用这个东西。
5,双击确实没有!这我记下来了!嘿嘿
2,对
3,对
4,它主要是为了适应不同的json格式,如果你按照我的json结构,那基本可以不用这个东西。
5,双击确实没有!这我记下来了!嘿嘿
16 楼
emoshoushou
2011-05-11
1请问,我想在点击图标的时候,异步加载子节点,应该怎么加?
2.我在onSelect: function (node){}里加一个异步加载。比如我下边取了数据然后加载到树上,为啥 appendTo($("#"+id),json);这句在IE报错呢
错误消息: 缺少对象
$.ajax({
url: "<%=path %>/deptJsonTreeAction.do? method=getDeptUsersTreeListQuery&deptId="+id,
cache: false,
success: function(json){
appendTo($("#"+id),json);
}
});
2.我在onSelect: function (node){}里加一个异步加载。比如我下边取了数据然后加载到树上,为啥 appendTo($("#"+id),json);这句在IE报错呢
错误消息: 缺少对象
$.ajax({
url: "<%=path %>/deptJsonTreeAction.do? method=getDeptUsersTreeListQuery&deptId="+id,
cache: false,
success: function(json){
appendTo($("#"+id),json);
}
});
17 楼
emoshoushou
2011-05-11
问一下,当取到的节点 newData 为平级的多个时,该怎么处理,
比如newData=[{userName=仲磊, userId=zhonglei, deptId=575}, {userName=张彦红, userId=zhangyanhong, deptId=575}, {userName=蔡皓, userId=caihao, deptId=575}];
这个该怎么加到树上,是treeEx.appendTo($("#"+id),json);么$("#"+id)取到的是要加载新节点的树节点。json为类似newData 的数据
我出来的是只有一个节点。而且是undefined
比如newData=[{userName=仲磊, userId=zhonglei, deptId=575}, {userName=张彦红, userId=zhangyanhong, deptId=575}, {userName=蔡皓, userId=caihao, deptId=575}];
这个该怎么加到树上,是treeEx.appendTo($("#"+id),json);么$("#"+id)取到的是要加载新节点的树节点。json为类似newData 的数据
我出来的是只有一个节点。而且是undefined
18 楼
emoshoushou
2011-05-11
上面的数据格式是这样的newData =[{"content":"仲磊","id":"zhonglei","deptId":575},{"content":"张彦红","id":"zhangyanhong","deptId":575},{"content":"蔡皓","id":"caihao","deptId":575}]
19 楼
emoshoushou
2011-05-11
如果您方便的话加一下QQ309413458,当面向您请教一下?
20 楼
satanultra
2011-05-11
emoshoushou 写道
如果您方便的话加一下QQ309413458,当面向您请教一下?
已经加你了~ 你可以看我的iteye博客 里边有一个新版的tree 可以支持异步加载