如何为树形菜单(TreeView)添加展开/收起动画与加载提示效果

13次阅读

如何为树形菜单(TreeView)添加展开/收起动画与加载提示效果

本文介绍如何使用 jquery 为树形菜单(treeview)添加平滑的展开/收起过渡动画、点击延迟响应及加载中提示,提升用户交互体验。

在构建可折叠的树形导航菜单时,原生的 toggle() 方法虽能实现显隐控制,但缺乏视觉反馈和节奏感。通过引入动画过渡与状态提示,可显著增强用户体验的专业性与友好度。以下将基于已有的 $.fn.treed 插件进行增强改造,实现三大核心效果:1 秒延迟展开/收起、滑动动画过渡、点击时显示加载提示

✅ 核心改造点说明

原插件中关键逻辑位于 branch.on(‘click’) 回调内,其中调用 $(this).children().children().toggle() 实现子菜单显隐。我们将其替换为更优雅的 slideToggle(),并插入加载提示与延时机制:

branch.on('click', function (e) {   if (this === e.target) {     var icon = $(this).children('i:first');     icon.toggleClass(openedClass + " " + closedClass);      // ① 插入加载提示元素     $(this).append('
Loading...
'); // ② 延迟 300ms 后执行动画(模拟“1秒延迟”效果) setTimeout(() => { $(this).find('.loading').remove(); // 移除加载提示 $(this).children().children().slideToggle(300); // 滑动切换子菜单 }, 300); } });

? 注意:此处 300ms 是动画持续时间,若需严格“点击后等待 1 秒再开始展开”,应将 setTimeout 延迟设为 1000,动画时长仍保持 300,例如:setTimeout(() => { $(this).find(‘.loading’).remove(); $(this).children().children().slideToggle(300); }, 1000); // 真正的 1 秒延迟触发

✅ 补充样式支持

为确保加载提示正常显示且不破坏布局,建议添加如下 css(兼容现有结构):

.loading {   font-style: italic;   font-size: 0.85em;   color: #666;   padding: 2px 0 4px 20px;   margin-top: 4px; } .loading .fa-spinner {   margin-right: 6px; }

同时,为避免 .loading 元素在动画过程中被意外隐藏,确保其不受 ul/li 的 overflow: hidden 或其他隐藏规则影响(当前 CSS 无此问题,但仍建议审查实际项目环境)。

✅ 完整增强版插件代码(精简整合)

$.fn.extend({   treed: function (o) {     var openedClass = 'fa-minus-circle';     var closedClass = 'fa-plus-circle';      if (typeof o !== 'undefined') {       if (typeof o.openedClass !== 'undefined') openedClass = o.openedClass;       if (typeof o.closedClass !== 'undefined') closedClass = o.closedClass;     }      return this.each(function () {       var tree = $(this).addClass('tree');       tree.find('li').has('ul').each(function () {         var branch = $(this);         branch           .prepend(``)           .addClass('branch')           .children('ul').hide(); // 初始隐藏子菜单(替代 toggle())          branch.on('click', function (e) {           if (this === e.target) {             var icon = $(this).children('i:first');             icon.toggleClass(openedClass + ' ' + closedClass);              $(this).append('
Loading...
'); setTimeout(() => { $(this).find('.loading').remove(); $(this).children('ul').slideToggle(300); }, 300); } }); }); // 支持通过 indicator、a、button 触发展开(保持原有逻辑) tree.find('.branch .indicator, .branch > a, .branch > button').on('click', function (e) { $(this).closest('li.branch').click(); if ($(this).is('a, button')) e.preventDefault(); }); }); } });

✅ 使用示例与初始化

  • TECH
    • Company Maintenance
    • Employees
      • Reports
        • Report1
        • Report2

✅ 注意事项与优化建议

  • 性能考虑:setTimeout 中的 dom 操作应确保 this 上下文有效;使用箭头函数可自动绑定,或改用 $.proxy
  • 可访问性(a11y):动画期间建议添加 aria-expanded 属性同步更新,便于屏幕阅读器识别状态。
  • 加载状态粒度:当前为每个节点独立加载提示;如需全局加载态(如请求远程数据),应结合 ajax 替换 setTimeout。
  • 动画中断处理:快速连续点击可能导致 slideToggle 动画队列积,可添加 .stop(true, true) 清除未完成动画:
    $(this).children('ul').stop(true, true).slideToggle(300);

通过以上增强,你的树形菜单将具备专业级的交互动效——既有视觉节奏感,又有明确的状态反馈,真正实现「所见即所得」的用户体验升级。

text=ZqhQzanResources