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 相关文章推荐
放弃用你的InnerHTML来输出HTML吧 jQuery Tmpl不详细讲解
Apr 20 Javascript
JavaScript中的Math.E属性使用详解
Jun 12 Javascript
如何解决手机浏览器页面点击不跳转浏览器双击放大网页
Jul 01 Javascript
jQuery 利用$.ajax 时获取原生XMLHttpRequest 对象的方法
Aug 25 Javascript
jQuery滚动监听实现商城楼梯式导航效果
Mar 06 Javascript
JS中的三个循环小结
Jun 20 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
Mar 19 Javascript
vue 路由子组件created和mounted不起作用的解决方法
Nov 05 Javascript
Vue中添加滚动事件设置的方法详解
Sep 14 Javascript
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
Jan 08 Vue.js
vue登录页实现使用cookie记住7天密码功能的方法
Feb 18 Vue.js
如何用Node.js编写内存效率高的应用程序
Apr 30 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
精致的人儿就要挑杯子喝咖啡
2021/03/03 冲泡冲煮
PHP定时自动生成静态HTML的实现代码
2010/06/20 PHP
php判断正常访问和外部访问的示例
2014/02/10 PHP
一个简单的JavaScript 日期计算算法
2009/09/11 Javascript
jquery 应用代码 方便的排序功能
2010/02/06 Javascript
Extjs学习过程中新手容易碰到的低级错误积累
2010/02/11 Javascript
JavaScript 构造函数 面相对象学习必备知识
2010/06/09 Javascript
javascript 拷贝节点cloneNode()使用介绍
2014/04/03 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
2015/09/01 Javascript
AngularJS 使用 UI Router 实现表单向导
2016/01/29 Javascript
js 求时间差的实现代码
2016/04/26 Javascript
js实现精确到秒的日期选择器完整实例
2016/04/30 Javascript
jquery代码规范让代码越来越好看
2017/02/03 Javascript
js模拟微博发布消息
2017/02/23 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
2017/04/12 Javascript
node app 打包工具pkg的具体使用
2019/01/17 Javascript
Vue使用Proxy监听所有接口状态的方法实现
2019/06/07 Javascript
使用layer模态框给新页面传值的方法
2019/09/27 Javascript
微信小程序自定义导航栏(模板化)
2019/11/15 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
2020/08/10 Javascript
[03:04]DOTA2超级联赛专访ZSMJ “莫名其妙”的逆袭
2013/05/23 DOTA
[03:39]DOTA2英雄梦之声_第05期_幽鬼
2014/06/23 DOTA
python实现银行管理系统
2019/10/25 Python
pycharm修改file type方式
2019/11/19 Python
浅谈matplotlib.pyplot与axes的关系
2020/03/06 Python
使用Keras预训练模型ResNet50进行图像分类方式
2020/05/23 Python
Python爬虫抓取指定网页图片代码实例
2020/07/24 Python
python多线程semaphore实现线程数控制的示例
2020/08/10 Python
python 如何调用 dubbo 接口
2020/09/24 Python
美国折扣网站:jClub
2017/08/07 全球购物
意大利领先的奢侈品在线时装零售商:MCLABELS
2020/10/13 全球购物
就业表自我评价分享
2014/02/06 职场文书
《陶罐和铁罐》教学反思
2014/02/19 职场文书
工作经常出错的检讨书
2014/09/13 职场文书
重温入党誓词主持词
2015/06/29 职场文书
老舍《猫》教学反思
2016/02/17 职场文书