使用Smarty在CMS中动态生成jQuery菜单的重复点击问题
解决Smarty+jQuery菜单重复点击先关后开的问题
嘿,我完全懂你遇到的这个糟心问题——点击同一个菜单项两次,它非要先收起再重新展开,折腾半天其实没必要对吧?咱们来把这个逻辑捋顺,分分钟搞定它。
问题根源
你现在的逻辑是只要点击某个带ID的菜单项,就先统一关闭所有.second-level-menu类的菜单,再展开当前对应的二级菜单。这就导致当你点击已经展开的菜单项时,第一步会把它关掉,第二步又立刻展开,就出现了这个多余的“先关再开”动作。
解决方案:给点击事件加状态判断
核心思路就是:点击菜单项时,先看看它对应的二级菜单是不是已经展开了。如果是,就直接跳过展开步骤(或者直接收起,看你想要的交互);如果不是,再执行“关闭其他+展开当前”的操作。
方案1:基于现有ID逻辑修改
如果不想改动太多现有代码,可以直接给每个ID的点击事件加判断:
$(document).ready(function() { $('#about-us').click(function() { // 假设#about-us对应的二级菜单是它的子元素或者相邻元素,这里用.next()示例,你根据实际结构调整 var $menu = $(this).next('.second-level-menu'); if ($menu.is(':visible')) { // 已经展开,直接收起 $menu.hide(); } else { // 先关闭所有其他二级菜单 $('.second-level-menu').hide(); // 再展开当前菜单 $menu.show(); } }); // 其他菜单项(比如#services)同理复制上述逻辑,或者用下面的通用方案更高效 });
方案2:通用类选择器(更推荐,减少重复代码)
如果你用Smarty循环生成菜单,建议给所有一级菜单项统一加一个类(比如first-level-item),同时用data-*属性关联对应的二级菜单ID,这样只需要写一段jQuery代码就能搞定所有菜单项:
Smarty模板代码:
{foreach from=$mainMenu item=menuItem} <div class="first-level-item" data-menu-id="menu-{$menuItem.id}"> {$menuItem.title} <!-- 二级菜单 --> <div id="menu-{$menuItem.id}" class="second-level-menu"> {foreach from=$menuItem.subItems item=subItem} <a href="{$subItem.url}">{$subItem.title}</a> {/foreach} </div> </div> {/foreach}
对应的jQuery代码:
$(document).ready(function() { $('.first-level-item').click(function() { var targetMenuId = $(this).data('menu-id'); var $targetMenu = $('#' + targetMenuId); // 判断当前菜单是否可见 if ($targetMenu.is(':visible')) { $targetMenu.hide(); } else { // 关闭所有其他二级菜单 $('.second-level-menu').hide(); // 展开当前目标菜单 $targetMenu.show(); } }); // 可选:阻止二级菜单内的点击触发父元素事件(避免菜单意外收起) $('.second-level-menu').click(function(e) { e.stopPropagation(); }); });
额外小提示
如果你想用更顺滑的动画效果,可以把hide()和show()换成slideUp()、slideDown()或者fadeToggle(),交互体验会更好:
// 替换成滑动动画 $targetMenu.slideToggle(); // 或者slideUp()/slideDown()
这样修改之后,点击已展开的菜单项时,要么直接收起,要么不会重复执行展开动作,完美解决你遇到的“先关再开”问题~
内容的提问来源于stack exchange,提问作者John Spartacus Scotcher
相关产品推荐
相关产品推荐

