在这里介绍一款小巧,功能强大,能拖拽,支持异步,且兼容性更高的jquery Tree插件:
效果如下:
选择:
拖拽:
jquery.simple.tree.官网地址: http://news.kg/wp-content/uploads/tree/(貌似已经打不开),不过因为操作比较简单,所以我们暂且用之。
前面讲过jquery EasyUI Tree插件,简单易用,但经过测试仍有诸多缺点,
例如:
1、兼容IE8的AJAX有问题。
2、如果异步返回数据较慢,将可能导致加载失败。
3、我们只使用其中的Tree功能,但其体积实在有点庞大。...
而我们需要的是,兼容性好,异步,体积小(用Tree的场景实在比较少,所以还是专用的代码文件比较好。)
好了,我们开始jquery.simple.tree之旅:
首先,要加载文件,一共三个:CSS、Jquery主文件、还有其本身的js文件;
然后,是定义Tree的代码;
最后,写出这根树的根节点HTML代码;
前台代码如下:
html代码
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
>
区域选择
</
title
>
<
link
rel
="stylesheet"
href
="/js/simpletree/jquery.simple.tree.css"
/>
<
script
type
="text/javascript"
src
="/js/jquery1.4.2.min.js"
></
script
>
<
script
type
="text/javascript"
src
="/js/simpletree/jquery.simple.tree.js"
></
script
>
<
script
type
="text/javascript"
>
var
simpleTreeCollection;
$(document).ready(
function
(){
simpleTreeCollection
=
$(
'
.simpleTree
'
).simpleTree({
autoclose:
true
,
afterClick:
function
(node){
alert(
"
您选择了:
"
+
$(
'
span:first
'
,node).text()
+
"
id为:
"
+
$(
'
span:first
'
,node).attr(
"
id
"
).substr(
2
));
//
此处为何要“.substr(2)”,是因为特殊原因,稍后可以得到解释.如果你仅仅需要取文字,这里可以不取ID。
},
afterDblClick:
function
(node){
//
alert("text-"+$('span:first',node).text());//双击事件
},
afterMove:
function
(destination, source, pos){
//
alert("destination-"+destination.attr('id')+" source-"+source.attr('id')+" pos-"+pos);//拖拽事件
},
afterAjax:
function
()
{
//
alert('Loaded');
},
animate:
true
//
,docToFolderConvert:true
});
});
</
script
>
</
head
>
<
body
>
<
ul
class
="simpleTree"
>
<
li
class
="root"
><
span
>
区域选择
</
span
>
<
ul
>
<
li
id
="root0"
class
="open"
><
span
>
中国
</
span
>
<
ul
class
="ajax"
>
<
li
id
='0'
>
{url:/common/GetGroupHtmlByPid.ashx?pid=0}
</
li
>
</
ul
>
</
li
>
</
ul
>
</
li
>
</
ul
>
</
body
>
</
html
>
后台响应代码:
GetGroupHtmlByPid.ashx.cs
public
class
GetGroupHtmlByPid : IHttpHandler
{
GroupManager group;
public
void
ProcessRequest(HttpContext context)
{
context.Response.ContentType
=
"
text/plain
"
;
int
parentId
=
-
1
;
int
type
=
0
;
string
resultStr
=
string
.Empty;
if
(
!
context.Request.QueryString[
"
pid
"
].IsNullOrEmpty())
{
Int32.TryParse(context.Request.QueryString[
"
pid
"
],
out
parentId);
}
if
(
!
context.Request.QueryString[
"
type
"
].IsNullOrEmpty())
{
Int32.TryParse(context.Request.QueryString[
"
type
"
],
out
type);
}
if
(parentId
>=
0
)
{
try
{
group
=
new
GroupManager((GroupType)type);
var subAg
=
group.AllGroups.Where(c
=>
c.ParentId
==
parentId);
resultStr
+=
"
<ul>
"
;
foreach
(Base_group item
in
subAg)
{
resultStr
+=
"
<li id=\
""
+ item.GroupId +
"
\
"
><span id=\
"
1_
"
+ item.GroupId +
"
\
"
>
"
+
item.GroupName
+
"
</span>
"
;
//
这里可以解释前台代码为何要.substr(2);
resultStr
+=
"
<ul class='ajax'><li>{url:/common/GetGroupHtmlByPid.ashx?pid=
"
+
item.GroupId
+
"
}</li></ul>
"
;
resultStr
+=
"
</li>
"
;
}
resultStr
+=
"
</ul>
"
;
}
catch
(Exception ex)
{
}
}
context.Response.Write(resultStr);
}
public
bool
IsReusable
{
get
{
return
false
;
}
}
}
后台看起来有点别扭,因为这个插件本身只支持HTML节点加载的,不过网上有人进行扩展了,用了JSON,不过个人感觉这对速度影响实在微乎其微,还是直接封装出HTML代码的。
总结一下jquery.simple.tree插件的优缺点:
优点:体积小,兼容性高,可异步,支持拖拽。
缺点:如果初始化的时候就需要异步加载,则需要手动更改它的几行代码。例如我的例子中。
本插件还有一个特别的功能,支持拖拽,可以用于后台维护无限分类,非常方便,有待读者自己去发掘,希望本文能够抛砖引玉,对你有所帮助!
源插件下载地址:http://plugins.jquery.com/project/SimpleTree
我的修改后的下载地址:simpletree.rar
我只修改了2行代码,以便在第一次初始化时就加载异步的内容。
续----拖拽操作客户端及脚本:
请注意,拖拽操作,如果你要移动到某一位置,则应该看到该位置出现一根横向的线线才可以.
我们知道拖拽有了被拖拽的节点ID,及拖拽目的节点ID,拖拽操作会触发afterMove(destination, source, pos)这个事件,于是我们需要做两件事:
一,创建一个input,以保存操作数,再写一个响应拖拽的函数;
二,创建一个保存按钮,发送最后操作的结果到服务器端.
函数如下(为了方便看清楚,我把整段都搬来):
页面脚本
<
script type
=
"
text/javascript
"
>
var
simpleTreeCollection;
$(document).ready(
function
(){
simpleTreeCollection
=
$(
'
.simpleTree
'
).simpleTree({
autoclose:
true
,
afterClick:
function
(node){
alert(
"
您选择了:
"
+
$(
'
span:first
'
,node).text()
+
"
id为:
"
+
$(
'
span:first
'
,node).attr(
"
id
"
).substr(
2
));
//
此处为何要“.substr(2)”,是因为特殊原因,稍后可以得到解释.如果你仅仅需要取文字,这里可以不取ID。
},
afterDblClick:
function
(node){
//
alert("text-"+$('span:first',node).text());//双击事件
},
afterMove:
function
(destination, source, pos){
moveNode(source.attr(
'
id
'
),destination.attr(
'
id
'
));
//
拖拽事件响应
},
afterAjax:
function
()
{
//
alert('Loaded');
},
animate:
true
//
,docToFolderConvert:true
});
});
//
响应函数
function
moveNode(sourceId,destId){
var
recs
=
$(
"
#moveRecs
"
).val();
var
strs
=
recs.match(eval(
"
/\\|
"
+
sourceId
+
"
,\\w+\\d+\\|/g
"
));
if
(strs
!=
null
){
//
源id有过一次拖动,则删除之
recs
=
recs.replace(strs,
"
|
"
);
$(
"
#moveRecs
"
).val(recs);
}
$(
"
#moveRecs
"
).val($(
"
#moveRecs
"
).val()
+
sourceId
+
"
,
"
+
destId
+
"
|
"
);
//
用栅栏把操作数隔开。
}
<
/
script>
在HTML页,我们加入两个控件,在页面结束后,绑定保存事件:
HTML片断
<
body
>
<
ul
class
="simpleTree"
>
...........
</
ul
><
input
type
="text"
id
="moveRecs"
value
="|"
style
="display:"
/><
input
type
="button"
id
="btnSaveActions"
value
="保存当前移动"
/>
</
body
>
</
html
>
<
script
language
="javascript"
>
$(
"
#btnSaveActions
"
).click(
function
(){
$.get(
"
/common/SaveMoveActions.aspx
"
, {
"
actions
"
:$(
'
#moveRecs
'
).val()
},
function
(returnvalue){
//
返回的 data 可以是 xmlDoc, jsonObj, html, text, 等等.
alert(returnvalue);
});
});
</
script
>
OK,客户端完成,接下来如何响应客户端请求,及如何做相关的数据处理操作,因为各人数据表及数据逻辑不尽相同,所以这里没有给出服务器端的操作代码。