jQuery 學(xué)習(xí)第六課 實(shí)現(xiàn)一個(gè)Ajax的TreeView
更新時(shí)間:2010年05月17日 22:51:27 作者:
TreeView是asp.net自帶的控件,不過(guò)自帶的控件在靈活性上有諸多限制。在jQuery的幫助下,自己實(shí)現(xiàn)一個(gè)TreeView也不困難。本文是前幾篇文章所講內(nèi)容的一個(gè)綜合演練。
最終實(shí)現(xiàn)的效果是一個(gè)目錄文件查看器,如圖所示:
其原理是,當(dāng)用戶單擊一個(gè)目錄的時(shí)候,將這個(gè)目錄的路徑發(fā)送給服務(wù)器端,服務(wù)器端返回這個(gè)目錄中的文件和目錄信息。在服務(wù)器端,定義一個(gè)如下的類來(lái)表示要傳遞的文件信息:
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是區(qū)分這條數(shù)據(jù)是一個(gè)文件還是文件夾,以便用不同的圖標(biāo)來(lái)顯示,最后一個(gè)Info是一些附加信息,在此例中沒(méi)有用到。根據(jù)一個(gè)路徑獲得目錄中的文件信息的C#代碼很簡(jiǎn)單,順便就貼在這里:
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數(shù)據(jù)的格式來(lái)傳遞這些信息。因此要將這些數(shù)據(jù)序列化。在.Net 3.5中,有現(xiàn)成的將實(shí)體類序列化成JSON數(shù)據(jù)的類,使用方法如下
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,則可以尋找一些第三方的組件,自己寫一個(gè)也不麻煩。
至此,服務(wù)器端的主要工作已經(jīng)完成了。新建一個(gè)Genric Handler文件,filelist.ashx,代碼如下,簡(jiǎn)單的響應(yīng)下請(qǐng)求,輸出數(shù)據(jù)即可:
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代碼的編寫。最主要的就是兩個(gè)事件,也就是鼠標(biāo)點(diǎn)擊發(fā)送ajax請(qǐng)求,處理返回的json數(shù)據(jù)生成html代碼,鼠標(biāo)再次點(diǎn)擊將html代碼清空。在這里,采用ul li來(lái)顯示這個(gè)treeview,在li中有一個(gè)不可見(jiàn)的span,里面包含了文件完整的路徑,它將用作發(fā)起ajax請(qǐng)求的參數(shù),但是對(duì)用戶是不可見(jiàn)的。
HTML代碼很簡(jiǎn)單,就4行:
<body>
<ul>
</ul>
</body>
首先需要初始化一個(gè)根目錄,例如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);
});
構(gòu)造好一個(gè)li結(jié)點(diǎn),添加到ul中去,然后設(shè)置下鼠標(biāo)動(dòng)作的樣式,最后為其綁定事件處理程序,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是否是同一個(gè)對(duì)象,以避免點(diǎn)擊子節(jié)點(diǎn)事件浮升的時(shí)候造成多次觸發(fā)。首先利用find和html函數(shù)獲得完整的路徑。構(gòu)造好一個(gè)ul節(jié)點(diǎn)并把它添加到當(dāng)前的li中。此時(shí)ul是空的,接下來(lái)發(fā)起ajax請(qǐng)求,獲得服務(wù)器端的數(shù)據(jù)。對(duì)每條數(shù)據(jù)生成一個(gè)li,其中對(duì)于是否是目錄加以判斷,生成帶有不同class的li,再加到node中。最后,不要忘記為新增的節(jié)點(diǎn)也綁定事件處理程序。代碼還是比較簡(jiǎn)單的,至于關(guān)閉目錄節(jié)點(diǎn)的代碼就更加簡(jiǎn)單了,
function CloseFolder(event) {
if (this == event.target)
$(this).find('ul').remove();
}
至此此范例已經(jīng)完成了。還少了幾句css,不再列出。
這個(gè)例子實(shí)現(xiàn)的功能和樣式都比較粗糙,不過(guò)在此基礎(chǔ)上做更多的擴(kuò)展和美化已經(jīng)不是難事。例如可以加上一點(diǎn)現(xiàn)成的動(dòng)畫效果:
function CloseFolder(event) {
if (this == event.target) {
var node = $(this).find('ul');
node.hide('slow', function() { $(this).find('ul').remove(); });
}
}
先隱藏,再刪除。類似地,可以加載完畢后立刻隱藏,再淡出。
其原理是,當(dāng)用戶單擊一個(gè)目錄的時(shí)候,將這個(gè)目錄的路徑發(fā)送給服務(wù)器端,服務(wù)器端返回這個(gè)目錄中的文件和目錄信息。在服務(wù)器端,定義一個(gè)如下的類來(lái)表示要傳遞的文件信息:
復(fù)制代碼 代碼如下:
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是區(qū)分這條數(shù)據(jù)是一個(gè)文件還是文件夾,以便用不同的圖標(biāo)來(lái)顯示,最后一個(gè)Info是一些附加信息,在此例中沒(méi)有用到。根據(jù)一個(gè)路徑獲得目錄中的文件信息的C#代碼很簡(jiǎn)單,順便就貼在這里:
復(fù)制代碼 代碼如下:
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數(shù)據(jù)的格式來(lái)傳遞這些信息。因此要將這些數(shù)據(jù)序列化。在.Net 3.5中,有現(xiàn)成的將實(shí)體類序列化成JSON數(shù)據(jù)的類,使用方法如下
復(fù)制代碼 代碼如下:
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,則可以尋找一些第三方的組件,自己寫一個(gè)也不麻煩。
至此,服務(wù)器端的主要工作已經(jīng)完成了。新建一個(gè)Genric Handler文件,filelist.ashx,代碼如下,簡(jiǎn)單的響應(yīng)下請(qǐng)求,輸出數(shù)據(jù)即可:
復(fù)制代碼 代碼如下:
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代碼的編寫。最主要的就是兩個(gè)事件,也就是鼠標(biāo)點(diǎn)擊發(fā)送ajax請(qǐng)求,處理返回的json數(shù)據(jù)生成html代碼,鼠標(biāo)再次點(diǎn)擊將html代碼清空。在這里,采用ul li來(lái)顯示這個(gè)treeview,在li中有一個(gè)不可見(jiàn)的span,里面包含了文件完整的路徑,它將用作發(fā)起ajax請(qǐng)求的參數(shù),但是對(duì)用戶是不可見(jiàn)的。
HTML代碼很簡(jiǎn)單,就4行:
復(fù)制代碼 代碼如下:
<body>
<ul>
</ul>
</body>
首先需要初始化一個(gè)根目錄,例如D:,代碼如下:
復(fù)制代碼 代碼如下:
$(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);
});
構(gòu)造好一個(gè)li結(jié)點(diǎn),添加到ul中去,然后設(shè)置下鼠標(biāo)動(dòng)作的樣式,最后為其綁定事件處理程序,LoadFile和CloseFolder。
復(fù)制代碼 代碼如下:
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是否是同一個(gè)對(duì)象,以避免點(diǎn)擊子節(jié)點(diǎn)事件浮升的時(shí)候造成多次觸發(fā)。首先利用find和html函數(shù)獲得完整的路徑。構(gòu)造好一個(gè)ul節(jié)點(diǎn)并把它添加到當(dāng)前的li中。此時(shí)ul是空的,接下來(lái)發(fā)起ajax請(qǐng)求,獲得服務(wù)器端的數(shù)據(jù)。對(duì)每條數(shù)據(jù)生成一個(gè)li,其中對(duì)于是否是目錄加以判斷,生成帶有不同class的li,再加到node中。最后,不要忘記為新增的節(jié)點(diǎn)也綁定事件處理程序。代碼還是比較簡(jiǎn)單的,至于關(guān)閉目錄節(jié)點(diǎn)的代碼就更加簡(jiǎn)單了,
復(fù)制代碼 代碼如下:
function CloseFolder(event) {
if (this == event.target)
$(this).find('ul').remove();
}
至此此范例已經(jīng)完成了。還少了幾句css,不再列出。
這個(gè)例子實(shí)現(xiàn)的功能和樣式都比較粗糙,不過(guò)在此基礎(chǔ)上做更多的擴(kuò)展和美化已經(jīng)不是難事。例如可以加上一點(diǎn)現(xiàn)成的動(dòng)畫效果:
復(fù)制代碼 代碼如下:
function CloseFolder(event) {
if (this == event.target) {
var node = $(this).find('ul');
node.hide('slow', function() { $(this).find('ul').remove(); });
}
}
先隱藏,再刪除。類似地,可以加載完畢后立刻隱藏,再淡出。
您可能感興趣的文章:
- 基于MVC5和Bootstrap的jQuery TreeView樹形控件(二)之?dāng)?shù)據(jù)支持json字符串、list集合
- 基于MVC5和Bootstrap的jQuery TreeView樹形控件(一)之?dāng)?shù)據(jù)支持json字符串、list集合
- jquery實(shí)現(xiàn)點(diǎn)擊TreeView文本父節(jié)點(diǎn)展開(kāi)/折疊子節(jié)點(diǎn)
- ASP.NET中基于JQUERY的高性能的TreeView補(bǔ)充
- 打造基于jQuery的高性能TreeView(asp.net)
- 為jQuery.Treeview添加右鍵菜單的實(shí)現(xiàn)代碼
- Jquery.TreeView結(jié)合ASP.Net和數(shù)據(jù)庫(kù)生成菜單導(dǎo)航條
- 選擇TreeView控件的樹狀數(shù)據(jù)節(jié)點(diǎn)的JS方法(jquery)
- jQuery 樹形結(jié)構(gòu)的選擇器
- jQuery treeview樹形結(jié)構(gòu)應(yīng)用
相關(guān)文章
jquery api參考 visualjquery 中國(guó)線路 速度快
jquery api參考 visualjquery 中國(guó)線路 速度快...2007-11-11
Jquery圖片滾動(dòng)與幻燈片的實(shí)例代碼
Jquery圖片滾動(dòng)與幻燈片的實(shí)例代碼,需要的朋友可以參考一下2013-04-04
jQuery實(shí)現(xiàn)仿百度帖吧頭部固定導(dǎo)航效果
這篇文章主要介紹了jQuery實(shí)現(xiàn)仿百度帖吧頭部固定導(dǎo)航效果,涉及jquery針對(duì)頁(yè)面高度計(jì)算與樣式的動(dòng)態(tài)添加及刪除技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-08-08
分享10篇優(yōu)秀的jQuery幻燈片制作教程及應(yīng)用案例
jQuery 是一個(gè)非常優(yōu)秀的 JavaScript 框架,使用簡(jiǎn)單靈活,同時(shí)還有許多成熟的插件可供選擇,它可以幫助你在項(xiàng)目中加入一些非常好的效果。2011-04-04
jquery數(shù)組之存放checkbox全選值示例代碼
使用jquery數(shù)組可以存放checkbox全選值,下面有個(gè)不錯(cuò)的示例,感興趣的朋友可以參考下2013-12-12
使用簡(jiǎn)潔的jQuery方法實(shí)現(xiàn)隔行換色功能
本篇文章主要介紹了使用簡(jiǎn)潔的jQuery方法實(shí)現(xiàn)隔行換色功能。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01
jQuery設(shè)置div一直在頁(yè)面頂部顯示的方法
如何讓div一直在頁(yè)面頂部,這種類似的效果大家都有見(jiàn)過(guò)的,實(shí)現(xiàn)的方法也有很多,在本文為大家詳細(xì)介紹下使用jquery是如何實(shí)現(xiàn)的,感興趣的朋友不要錯(cuò)過(guò)2013-10-10
jquery.Callbacks的實(shí)現(xiàn)詳解
這篇文章主要給大家介紹的是jQuery.Callback()的實(shí)現(xiàn),這個(gè)函數(shù)常見(jiàn)的應(yīng)用場(chǎng)景是事件觸發(fā)機(jī)制,也就是設(shè)計(jì)模式中的觀察者(發(fā)布、訂閱機(jī)制),目前Callbacks對(duì)象用于queue、ajax、Deferred對(duì)象中,下面通過(guò)這篇文章來(lái)詳細(xì)看看關(guān)于jquery.Callbacks實(shí)現(xiàn)的介紹吧。2016-11-11

