jQuery+XML+Ajax实现无刷新动态树形结构教程
本文将展示如何使用C#作为后端语言生成XML数据,并结合jQuery的Ajax技术在前端实现一个无刷新的动态树形结构。该方案通过异步加载子节点XML来构建层级菜单,适合需要动态加载大量数据的场景。
核心原理
实现无刷新树形结构的核心思路是利用 <ul> 嵌套 <li> 的HTML标准结构。后端根据传入的父节点ID,查询数据库或内存中的数据,将其转换为XML格式返回给前端。前端接收到XML后,解析节点信息并动态追加到DOM中,从而形成树状层级。已展开的节点在再次点击时不进行重复请求,而是直接控制显示或隐藏状态,以优化性能。
准备条件
- 开发环境:Visual Studio(支持ASP.NET Web Forms)及浏览器支持jQuery库。
- 数据模型:需要一个包含唯一ID、父节点ID和名称的数据结构(如示例中的Product类)。
- 依赖库:页面需引用 jQuery JavaScript 库。
具体操作步骤
第1步:后端生成XML数据
目的:提供标准化的XML数据源,供前端解析。
入口:WebForm1.aspx.cs 页面代码。
动作:在页面加载事件中获取请求参数中的 parentID,调用 GetXML 方法。
关键逻辑:
- 使用 LINQ 从数据集合中筛选出指定父ID下的子节点列表。
- 利用
XElement构建根节点 "textTree" 及多个 "value" 子节点,每个子节点包含id属性和文本内容(名称)。 - 将生成的XML对象序列化并写入
Response.OutputStream,同时设置响应类型为text/xml。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Linq;
namespace WebApplication3
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// 获取前端传来的父节点ID
int id = Convert.ToInt32(Request["parentID"]);
GetXML(id);
}
// 模拟数据源
public IList<Product> GetList()
{
return new List<Product>()
{
new Product(){ Id=1, ParentId=0, HasChild=1, Name="aaaaa" },
new Product(){ Id=2, ParentId=1, HasChild=1, Name="bbbb1" },
new Product(){ Id=3, ParentId=2, HasChild=0, Name="ccccc2" },
new Product(){ Id=4, ParentId=2, HasChild=0, Name="ddddd3" },
new Product(){ Id=5, ParentId=1, HasChild=0, Name="eeeeee4" },
new Product(){ Id=6, ParentId=3, HasChild=0, Name="ffffff5" },
new Product(){ Id=7, ParentId=4, HasChild=0, Name="ggggggg6" },
new Product(){ Id=8, ParentId=7, HasChild=0, Name="hhhhhhh7" },
new Product(){ Id=9, ParentId=0, HasChild=0, Name="jjjjjjj8" },
new Product(){ Id=10,ParentId=0, HasChild=0, Name="yyyyyyyy9" }
};
}
/// <summary>
/// 通过父节点读取子节点并且拼接成xml给前台
/// </summary>
public void GetXML(int parentId)
{
// 筛选当前层级的子节点
List<Product> list = GetList().Where(x => x.ParentId == parentId).ToList();
// 构建XML结构
XElement xElement = new XElement("textTree");
foreach (Product p in list)
{
// 添加value节点,属性为id,内容为Name
xElement.Add(new XElement("value", new XAttribute("id", p.Id), p.Name));
}
// 为了调试可保存文件到本地,实际部署建议移除
xElement.Save("d:\\kissnana.xml");
// 转换并输出XML响应
XmlDocument xdocument = new XmlDocument();
xdocument.LoadXml(xElement.ToString());
Response.ContentType = "text/xml";
xdocument.Save(Response.OutputStream);
Response.End();
}
}
public class Product
{
public int Id { set; get; }
public int ParentId { set; get; }
public int HasChild { set; get; }
public string Name { set; get; }
}
}
第2步:前端HTML结构设计
目的:提供树的容器和触发入口。
入口:WebForm1.aspx HTML视图。
动作:
- 创建一个按钮用于初始化树的加载,点击时调用
LoadXml(0),初始父ID通常为0。 - 创建一个空的
<div id="root">作为树的根容器,后续所有<ul>都将插入其中。
代码如下:
<body>
<form id="form1" runat="server">
<input type="button" value="text" onclick="LoadXml(0)" />
<div id="root"></div>
</form>
</body>
第3步:前端JS逻辑实现
目的:处理Ajax请求,渲染DOM树,绑定交互事件。
入口:页面内的 <script> 标签。
动作:
- LoadXml(id):封装Ajax请求。
- 类型:POST。
- URL:指向后台aspx页面,携带参数
parentID。 - 数据类型:指定为
xml。 - 成功回调:执行
createTree函数。
- createTree(xml):解析XML并渲染。
- 判断是否为首次加载,确定挂载点
obj。首次挂载至#root,后续挂载至当前的li。 - 在当前上下文中追加
<ul class="ULfather">。 - 遍历XML中的
value节点,为每个节点创建<li>和<a>元素。 - 绑定
a标签的点击事件:检查同级是否已存在<ul>。若不存在,说明未加载子节点,则递归调用LoadXml;若存在,则调用GetDisplayOrNot切换显隐。
- 判断是否为首次加载,确定挂载点
- GetDisplayOrNot(obj):节点显隐控制。
- 通过jQuery选择器获取目标
ul。 - 根据
:hidden状态切换CSS的display属性为block或none。
- 通过jQuery选择器获取目标
<script type="text/javascript"
var object1 = null;
function LoadXml(id) {
$.ajax({
type: "post",
url:"WebForm1.aspx?parentID="+id,
dataType:"xml",
success: createTree
});
}
// 每次父节点产生一个ul孩子并且ajax读取该父亲的直接儿子,拼接树
function createTree(xml) {
var obj = object1 == null ? ("#root") : (object1);
$(obj).append("< UL class='ULfather'>");
$(xml).find("value").each(function() {
// 拼接li和a,属性通过xml中的value节点的属性id和节点文本进行拼接
$(obj).children(".ULfather").append("< li><a id = " + $(this).attr("id") + "> " + $(this).text() + "< /a></li >");
var alink = "#" + $(this).attr("id");
$(alink).bind("click", function() {
// 如果超链接下个元素是ul的话,说明数据已经绑过
if ($(alink + " + ul").size() <= 0) {
object1 = $(alink).parent("li");
LoadXml($(this).attr("id"))
}
else {
GetDisplayOrNot($(alink));
}
});
});
}
//节点显示或影藏
function GetDisplayOrNot(obj) {
if ($(obj).parent("li").children("ul").is(": hidden ")) {
$(obj).parent("li").children("ul").css("display", "block");
}
else {
$(obj).parent("li").children("ul").css("display", "none");
}
}
</script>
注意事项
- 性能优化:示例代码中将XML保存到了本地磁盘
d:\\kissnana.xml,在生产环境中请删除此部分代码以避免权限问题或IO性能损耗。 - DOM更新:代码通过判断子级
ul是否存在来决定是否重新请求,这是一种简单的缓存机制,确保已加载过的节点不会重复请求后台。 - 样式缺失:原始示例不包含CSS,因此树形结构默认无缩进和样式。如需美观展示,建议添加相应的CSS类来控制缩进和箭头图标。
总结
本教程展示了基于C#和jQuery的经典树形组件实现方式。虽然现代前端框架(如Vue、React)提供了更便捷的树形控件,但理解这种原生DOM操作与Ajax配合的逻辑,对于排查老项目Bug或理解基本原理非常有帮助。以上就是jQuery Ajax异步加载XML构建动态树形菜单的详细内容,更多关于C#前端交互的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









