如何为Treeview菜单的展开/收起添加JavaScript特效
为Treeview添加延迟展开/收起与加载图标特效
需求说明
点击Treeview菜单项后延迟1秒执行展开/收起操作;点击过程中显示加载图标,展开、收起操作均需包含该效果。
修改后的完整代码
JavaScript 代码
$.fn.extend({ treed: function(o) { var openedClass = 'fa-minus-circle'; var closedClass = 'fa-plus-circle'; var loadingClass = 'fa-spinner fa-spin'; // 定义加载图标类 if (typeof o != 'undefined') { if (typeof o.openedClass != 'undefined') { openedClass = o.openedClass; } if (typeof o.closedClass != 'undefined') { closedClass = o.closedClass; } }; var tree = $(this); tree.addClass("tree"); tree.find('li').has("ul").each(function() { var branch = $(this); branch.prepend("<i class='indicator fas " + closedClass + "'></i>"); branch.addClass('branch'); branch.on('click', function(e) { if (this == e.target && !$(this).hasClass('loading')) { // 防止重复触发 var $this = $(this); var icon = $this.children('i:first'); // 切换为加载状态 $this.addClass('loading'); icon.removeClass(openedClass + " " + closedClass).addClass(loadingClass); // 延迟1秒执行展开/收起 setTimeout(function() { // 恢复图标与状态,执行显示/隐藏 icon.removeClass(loadingClass).toggleClass(openedClass + " " + closedClass); $this.children().children().toggle(); $this.removeClass('loading'); }, 1000); } }) branch.children().children().toggle(); }); // 图标点击事件代理 tree.find('.branch .indicator').each(function() { $(this).on('click', function() { $(this).closest('li').click(); }); }); // 锚点点击事件代理 tree.find('.branch>a').each(function() { $(this).on('click', function(e) { $(this).closest('li').click(); e.preventDefault(); }); }); // 按钮点击事件代理 tree.find('.branch>button').each(function() { $(this).on('click', function(e) { $(this).closest('li').click(); e.preventDefault(); }); }); } }); // 初始化Treeview $('#tree1').treed(); $('#tree2').treed({ openedClass: 'fa-folder-open', closedClass: 'fa-folder' });
CSS 代码
.tree, .tree ul { margin: 0; padding: 0; list-style: none; margin-left: 10px; } .tree ul { margin-left: 1em; position: relative } .tree ul ul { margin-left: .5em } .tree ul:before { content: ""; display: block; width: 0; position: absolute; top: 0; bottom: 0; left: 0; border-left: 1px solid } .tree li { margin: 0; padding: 0 1em; line-height: 2em; color: #369; font-weight: 700; position: relative; cursor: pointer; /* 增加点击指针样式 */ } .tree ul li:before { content: ""; display: block; width: 10px; height: 0; border-top: 1px solid; margin-top: -1px; position: absolute; top: 1em; left: 0 } .tree ul li:last-child:before { background: #fff; height: auto; top: 1em; bottom: 0 } .indicator { margin-right: 5px; } /* 加载状态下禁止重复点击 */ .tree li.loading { pointer-events: none; } .tree li a { text-decoration: none; color: #369; } .tree li button, .tree li button:active, .tree li button:focus { text-decoration: none; color: #369; border: none; background: transparent; margin: 0; padding: 0; outline: 0; }
HTML 代码
<div class="row"> <div class="col-md-4"> <ul id="tree2"> <li> <a href="#">TECH</a> <ul> <li>Company Maintenance</li> <li> Employees <ul> <li> Reports <ul> <li>Report1</li> <li>Report2</li> <li>Report3</li> </ul> </li> <li>Employee Maint.</li> </ul> </li> <li>Human Resources</li> </ul> </li> <li> XRP <ul> <li>Company Maintenance</li> <li> Employees <ul> <li> Reports <ul> <li>Report1</li> <li>Report2</li> <li>Report3</li> </ul> </li> <li>Employee Maint.</li> </ul> </li> <li>Human Resources</li> </ul> </li> </ul> </div> </div> <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css" integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
关键改动说明
- 加载状态控制:新增
loadingClass定义旋转加载图标,点击时先切换为加载图标,同时给li添加loading类禁用重复点击,避免多次触发事件。 - 延迟执行逻辑:用
setTimeout实现1秒延迟,延迟结束后恢复展开/收起图标,执行子元素显示/隐藏操作,最后移除加载状态。 - 交互体验优化:给li添加
cursor: pointer样式明确可点击性;加载状态下通过pointer-events: none禁止重复操作。
内容的提问来源于stack exchange,提问作者Andandydongola
相关产品推荐
相关产品推荐

