jQuery+XML+Ajax实现无刷新动态树形结构教程

云舒
云舒
发布时间:2026-10-16 | 6人浏览过
原创

本文将展示如何使用C#作为后端语言生成XML数据,并结合jQuery的Ajax技术在前端实现一个无刷新的动态树形结构。该方案通过异步加载子节点XML来构建层级菜单,适合需要动态加载大量数据的场景。

核心原理

实现无刷新树形结构的核心思路是利用 <ul> 嵌套 <li> 的HTML标准结构。后端根据传入的父节点ID,查询数据库或内存中的数据,将其转换为XML格式返回给前端。前端接收到XML后,解析节点信息并动态追加到DOM中,从而形成树状层级。已展开的节点在再次点击时不进行重复请求,而是直接控制显示或隐藏状态,以优化性能。

准备条件

  1. 开发环境:Visual Studio(支持ASP.NET Web Forms)及浏览器支持jQuery库。
  2. 数据模型:需要一个包含唯一ID、父节点ID和名称的数据结构(如示例中的Product类)。
  3. 依赖库:页面需引用 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> 标签。

动作:

  1. LoadXml(id):封装Ajax请求。
    • 类型:POST。
    • URL:指向后台aspx页面,携带参数 parentID。
    • 数据类型:指定为 xml。
    • 成功回调:执行 createTree 函数。
  2. createTree(xml):解析XML并渲染。
    • 判断是否为首次加载,确定挂载点 obj。首次挂载至 #root,后续挂载至当前的 li。
    • 在当前上下文中追加 <ul class="ULfather">。
    • 遍历XML中的 value 节点,为每个节点创建 <li> 和 <a> 元素。
    • 绑定 a 标签的点击事件:检查同级是否已存在 <ul>。若不存在,说明未加载子节点,则递归调用 LoadXml;若存在,则调用 GetDisplayOrNot 切换显隐。
  3. GetDisplayOrNot(obj):节点显隐控制。
    • 通过jQuery选择器获取目标 ul。
    • 根据 :hidden 状态切换CSS的 display 属性为 block 或 none。
<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#前端交互的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表