jQuery 学习第六课 实现一个Ajax的TreeView


Posted in Javascript onMay 17, 2010

最终实现的效果是一个目录文件查看器,如图所示: 
jQuery 学习第六课 实现一个Ajax的TreeView 
其原理是,当用户单击一个目录的时候,将这个目录的路径发送给服务器端,服务器端返回这个目录中的文件和目录信息。在服务器端,定义一个如下的类来表示要传递的文件信息:

public class FileInformation 
{ 
public string FullPath 
{ 
get; set; 
} 
public string Name 
{ 
get; set; 
} 
public string Info 
{ 
get; set; 
} 
public bool IsFolder 
{ 
get; set; 
} 
}

其中FullPath是文件的完整路径,用于获取它的子文件夹/文件用,Name是文件的名字,用于显示,IsFolder是区分这条数据是一个文件还是文件夹,以便用不同的图标来显示,最后一个Info是一些附加信息,在此例中没有用到。根据一个路径获得目录中的文件信息的C#代码很简单,顺便就贴在这里:
public class FileManager 
{ 
public static List<FileInformation> GetFolderContent(string fullpath) 
{ 
List<FileInformation> res = new List<FileInformation>(); 
DirectoryInfo info = new DirectoryInfo(fullpath); 
if (info.Exists) 
{ 
foreach (DirectoryInfo d in info.GetDirectories()) 
{ 
res.Add(new FileInformation 
{ 
FullPath = d.FullName, Name = d.Name,IsFolder = true, 
Info = "Any More Information goes here" 
}); 
} 
foreach (FileInfo f in info.GetFiles()) 
{ 
res.Add(new FileInformation 
{ 
FullPath = f.FullName,Name = f.Name,IsFolder = false, 
Info = "Any More Information goes here" 
}); 
} 
} 
return res; 
} 
}

此例中采用JSON数据的格式来传递这些信息。因此要将这些数据序列化。在.Net 3.5中,有现成的将实体类序列化成JSON数据的类,使用方法如下
public static string ToJson<T>(T obj) 
{ 
DataContractJsonSerializer d = new DataContractJsonSerializer(typeof(T)); 
System.IO.MemoryStream ms = new System.IO.MemoryStream(); 
d.WriteObject(ms, obj); 
string strJSON = System.Text.Encoding.UTF8.GetString(ms.ToArray()); 
ms.Close(); 
return strJSON; 
}

如果是.net 2.0,则可以寻找一些第三方的组件,自己写一个也不麻烦。
至此,服务器端的主要工作已经完成了。新建一个Genric Handler文件,filelist.ashx,代码如下,简单的响应下请求,输出数据即可:
public class FileList : IHttpHandler { 
public void ProcessRequest (HttpContext context) { 
string path = context.Request.QueryString["path"]; 
string data = JsonHelper.ToJson<List<FileInformation>>(FileManager.GetFolderContent(path)); 
context.Response.Write(data); 
} 
public bool IsReusable { 
get { 
return false; 
} 
} 
}

下面考虑客户端html代码的编写。最主要的就是两个事件,也就是鼠标点击发送ajax请求,处理返回的json数据生成html代码,鼠标再次点击将html代码清空。在这里,采用ul li来显示这个treeview,在li中有一个不可见的span,里面包含了文件完整的路径,它将用作发起ajax请求的参数,但是对用户是不可见的。
HTML代码很简单,就4行:
<body> 
<ul> 
</ul> 
</body>

首先需要初始化一个根目录,例如D:,代码如下:
$(function() { 
$('<li class="folder">D:\\<span class="fullpath">D:\\</span></li>').appendTo('ul'); 
$('li').hover(function() { 
$(this).css('cursor', 'pointer'); 
}, 
function() { $(this).css('cursor', 'default'); }); 
$('li.folder').toggle(LoadFile, CloseFolder); 
});

构造好一个li结点,添加到ul中去,然后设置下鼠标动作的样式,最后为其绑定事件处理程序,LoadFile和CloseFolder。
function LoadFile(event) { 
if (this == event.target) { 
var path = $(this).find('span').html(); 
var node = $('<ul>'); 
$(this).append(node); 
$.getJSON('filelist.ashx', { path: path }, function(data) { 
$.each(data, function() { 
if (this.IsFolder) { 
node.append($('<li>').addClass('folder').html(this.Name).append($('<span>').addClass('fullpath').html(this.FullPath))); 
} 
else { 
node.append($('<li>').addClass('file').html(this.Name).append($('<span>').addClass('fullpath').html(this.FullPath))); 
} 
}); 
node.find('li.folder').toggle(LoadFile, CloseFolder); 
}); 
} 
}

首先要判断event的target和this是否是同一个对象,以避免点击子节点事件浮升的时候造成多次触发。首先利用find和html函数获得完整的路径。构造好一个ul节点并把它添加到当前的li中。此时ul是空的,接下来发起ajax请求,获得服务器端的数据。对每条数据生成一个li,其中对于是否是目录加以判断,生成带有不同class的li,再加到node中。最后,不要忘记为新增的节点也绑定事件处理程序。代码还是比较简单的,至于关闭目录节点的代码就更加简单了,
function CloseFolder(event) { 
if (this == event.target) 
$(this).find('ul').remove(); 
}

至此此范例已经完成了。还少了几句css,不再列出。
这个例子实现的功能和样式都比较粗糙,不过在此基础上做更多的扩展和美化已经不是难事。例如可以加上一点现成的动画效果:
function CloseFolder(event) { 
if (this == event.target) { 
var node = $(this).find('ul'); 
node.hide('slow', function() { $(this).find('ul').remove(); }); 
} 
}

先隐藏,再删除。类似地,可以加载完毕后立刻隐藏,再淡出。
Javascript 相关文章推荐
Javascript 强制类型转换函数
May 17 Javascript
ASP.NET jQuery 实例3 (在TextBox里面阻止复制、剪切和粘贴事件)
Jan 13 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
May 14 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
Nov 24 Javascript
js常用DOM方法详解
Feb 04 Javascript
关于vue-router的beforeEach无限循环的问题解决
Sep 09 Javascript
JavaScript 下载svg图片为png格式
Jun 21 Javascript
layui异步加载table表中某一列数据的例子
Sep 16 Javascript
file-loader打包图片文件时路径错误输出为[object-module]的解决方法
Jan 03 Javascript
JS前端广告拦截实现原理解析
Feb 17 Javascript
VSCode搭建React Native环境
May 07 Javascript
JavaScript实现与web通信的方法详解
Aug 07 Javascript
jQuery 学习第五课 Ajax 使用说明
May 17 #Javascript
jQuery实现的立体文字渐变效果
May 17 #Javascript
jQuery实现的类flash菜单效果代码
May 17 #Javascript
Jquery Select操作方法集合脚本之家特别版
May 17 #Javascript
JQuery select标签操作代码段
May 16 #Javascript
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
May 15 #Javascript
Jquery 最近浏览过的商品的功能实现代码
May 14 #Javascript
You might like
千呼万唤始出来,DOTA2勇士令状不朽宝藏Ⅱ现已推出
2020/08/25 DOTA
nginx+php-fpm配置文件的组织结构介绍
2012/11/07 PHP
php设计模式之命令模式使用示例
2014/03/02 PHP
浅析php工厂模式
2014/11/25 PHP
thinkphp备份数据库的方法分享
2015/01/04 PHP
form表单传递数组数据、php脚本接收的实例
2017/02/09 PHP
yii框架无限极分类的实现方法
2017/04/08 PHP
javascript之对系统的toFixed()方法的修正
2007/05/08 Javascript
js操作ajax返回的json的注意问题!
2010/02/23 Javascript
js 处理URL实用技巧
2010/11/23 Javascript
一个基于jquery的文本框记数器
2012/09/19 Javascript
jQuery数据类型小结(14个)
2016/01/08 Javascript
浅谈JavaScript 数据属性和访问器属性
2016/09/01 Javascript
基于jQuery ligerUI实现分页样式
2016/09/18 Javascript
网站申请不到支付宝接口、微信接口,免接口收款实现方式几种解决办法
2016/12/14 Javascript
原生js实现节日时间倒计时功能
2017/01/18 Javascript
Bootstrap导航中表单简单实现代码
2017/03/06 Javascript
angularJs中$http获取后台数据的实例讲解
2018/08/08 Javascript
解决layui上传文件提示上传异常,实际文件已经上传成功的问题
2018/08/19 Javascript
ES10 特性的完整指南小结
2019/03/04 Javascript
[48:22]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[56:57]LGD vs VP 2019DOTA2国际邀请赛淘汰赛 胜者组赛BO3 第一场 8.20.mp4
2019/08/22 DOTA
Python使用functools模块中的partial函数生成偏函数
2016/07/02 Python
Windows安装Python、pip、easy_install的方法
2017/03/05 Python
Python基于高斯消元法计算线性方程组示例
2018/01/17 Python
django 微信网页授权认证api的步骤详解
2019/07/30 Python
python-tornado的接口用swagger进行包装的实例
2019/08/29 Python
Python3 实现减少可调用对象的参数个数
2019/12/20 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
STP的判定过程
2012/10/01 面试题
飞利信loadrunner和软件测试笔试题
2012/09/22 面试题
企业安全生产演讲稿
2014/05/09 职场文书
勿忘国耻9.18演讲稿(经典篇)
2014/09/14 职场文书
教师批评与自我批评(群众路线)
2014/10/15 职场文书
优秀员工自荐书
2015/03/06 职场文书
4种非常实用的python内置数据结构
2021/04/28 Python