
本文介绍如何使用 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
- Reports
✅ 注意事项与优化建议
- 性能考虑:setTimeout 中的 DOM 操作应确保 this 上下文有效;使用箭头函数可自动绑定,或改用 $.proxy。
- 可访问性(a11y):动画期间建议添加 aria-expanded 属性同步更新,便于屏幕阅读器识别状态。
- 加载状态粒度:当前为每个节点独立加载提示;如需全局加载态(如请求远程数据),应结合 AJAX 替换 setTimeout。
-
动画中断处理:快速连续点击可能导致 slideToggle 动画队列堆积,可添加 .stop(true, true) 清除未完成动画:
$(this).children('ul').stop(true, true).slideToggle(300);
通过以上增强,你的树形菜单将具备专业级的交互动效——既有视觉节奏感,又有明确的状态反馈,真正实现「所见即所得」的用户体验升级。









