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 相关文章推荐
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
Mar 24 Javascript
根据表格中的某一列进行排序的javascript代码
Nov 29 Javascript
JavaScript数据类型详解
Apr 01 Javascript
JS实现物体带缓冲的间歇运动效果示例
Dec 22 Javascript
微信小程序 解决请求服务器手机预览请求不到数据的方法
Jan 04 Javascript
浅谈Node.js CVE-2017-14849 漏洞分析(详细步骤)
Nov 10 Javascript
解析Vue2 dist 目录下各个文件的区别
Nov 22 Javascript
详解如何在项目中使用jest测试react native组件
Feb 09 Javascript
Node.js+Express+Mysql 实现增删改查
Apr 03 Javascript
详解wepy开发小程序踩过的坑(小结)
May 22 Javascript
Nuxt.js nuxt-link与router-link的区别说明
Nov 06 Javascript
React实现todolist功能
Dec 28 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
第五节 克隆 [5]
2006/10/09 PHP
javascript对象的property和prototype是这样一种关系
2007/03/24 Javascript
从父页面读取和操作iframe中内容方法
2009/07/25 Javascript
js数组Array sort方法使用深入分析
2013/02/21 Javascript
js arguments,jcallee caller用法总结
2013/11/30 Javascript
Jquery获得控件值的三种方法总结
2014/02/13 Javascript
详谈jQuery中的this和$(this)
2014/11/13 Javascript
原生js获取元素样式的简单方法
2016/08/06 Javascript
微信小程序 触控事件详细介绍
2016/10/17 Javascript
Angular2关于@angular/cli默认端口号配置的问题
2017/07/15 Javascript
Node.js  REPL (交互式解释器)实例详解
2017/08/06 Javascript
vue mounted组件的使用
2018/06/18 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
2018/10/26 Javascript
Vue中rem与postcss-pxtorem的应用详解
2019/11/20 Javascript
javascript全局自定义鼠标右键菜单
2020/12/08 Javascript
[08:54]《一刀刀一天》之DOTA全时刻18:十九支奔赴西雅图队伍全部出炉
2014/06/04 DOTA
[41:52]2018DOTA2亚洲邀请赛3月29日 小组赛A组 TNC VS OpTic
2018/03/30 DOTA
python3.0 模拟用户登录,三次错误锁定的实例
2017/11/02 Python
Python基础教程之内置函数locals()和globals()用法分析
2018/03/16 Python
Python爬虫实战:分析《战狼2》豆瓣影评
2018/03/26 Python
解决Python 爬虫URL中存在中文或特殊符号无法请求的问题
2018/05/11 Python
python训练数据时打乱训练数据与标签的两种方法小结
2018/11/08 Python
Python Scapy随心所欲研究TCP协议栈
2018/11/20 Python
Python不同目录间进行模块调用的实现方法
2019/01/29 Python
使用python进行广告点击率的预测的实现
2019/07/04 Python
纯CSS打造(无图像无js)的非常流行的讲话(语音)气泡效果
2012/12/28 HTML / CSS
英国灯具和灯泡网上商店:Lights.co.uk
2018/02/02 全球购物
英国50岁以上人群的交友网站:Ourtime
2018/03/28 全球购物
PHP面试题及答案二
2015/05/23 面试题
C面试题
2015/10/08 面试题
会计专业自我鉴定范文
2013/12/29 职场文书
怀孕辞职信怎么写
2015/02/28 职场文书
2015年调度员工作总结
2015/04/30 职场文书
安全事故隐患排查治理制度
2015/08/05 职场文书
咖啡厅里的创业计划书
2019/08/21 职场文书
html css3不拉伸图片显示效果
2021/06/07 HTML / CSS