Ace Responsive Menu平板展开视图点击快速上滑问题求助
我帮你找到了问题所在!这个菜单在平板展开视图(窗口宽度大于设置的resizeWidth但设备是平板)里点击菜单快速上滑的问题,根源是事件绑定和解绑不彻底,以及窗口 resize 时的状态判断逻辑有漏洞。
问题分析
- 当窗口从小于
resizeWidth切换到大于resizeWidth时,原代码虽然移除了collapse类,但没有彻底解绑点击事件,也没有重新正确绑定鼠标事件,导致鼠标事件和点击事件冲突,触发了意外的菜单收起行为。 - 另外,
menuCollapse函数里的状态重置逻辑不够严谨,在切换到展开视图时,没有确保所有子菜单的状态正确复位。
修改后的完整JS代码
/* Ace Responsive Menu Plugin Version: 1.0 Author: Samson.Onna Email : samson3d@gmail.com ----------------------------------------*/ (function ($) { $.fn.aceResponsiveMenu = function (options) { //plugin's default options var defaults = { resizeWidth: '768', animationSpeed: 'slow', accoridonExpAll: false }; //Variables var options = $.extend(defaults, options), opt = options, $resizeWidth = parseInt(opt.resizeWidth), // 转为数字避免字符串比较问题 $animationSpeed = opt.animationSpeed, $expandAll = opt.accoridonExpAll, $aceMenu = $(this), $menuStyle = $(this).attr('data-menu-style'); // Initilizing $aceMenu.find('ul').addClass("sub-menu"); $aceMenu.find('ul').siblings('a').append('<span class="arrow "></span>'); if ($menuStyle == 'accordion') { $(this).addClass('collapse'); } // 统一的事件绑定/解绑函数 function setupMenuEvents() { // 先解绑所有旧事件,避免冲突 $aceMenu.off('mouseover', '> li a').off('mouseleave', 'li').off('click', '> li a'); if ($aceMenu.hasClass('collapse')) { // 折叠模式(移动端/accordion)绑定点击事件 $aceMenu.on('click', '> li a', function (e) { // 阻止链接默认行为,避免跳转干扰菜单动画 e.preventDefault(); if ($(this).parent().hasClass('menu-active')) { $(this).parent().children('.sub-menu').slideUp().removeClass('slide'); $(this).parent().removeClass('menu-active'); } else { if ($expandAll == true) { $(this).parent().addClass('menu-active').children('.sub-menu').slideDown($animationSpeed).addClass('slide'); return; } $(this).parent().siblings().removeClass('menu-active'); $(this).parent('li').siblings().children('.sub-menu').slideUp().removeClass('slide'); $(this).parent().addClass('menu-active').children('.sub-menu').slideDown($animationSpeed).addClass('slide'); } }); } else { // 展开模式(桌面端)绑定鼠标事件 $aceMenu.on('mouseover', '> li a', function () { $(this).parent('li').siblings().children('.sub-menu').stop(true, true).slideUp($animationSpeed).removeClass('slide').removeAttr('style'); $(this).parent().addClass('menu-active').children('.sub-menu').slideDown($animationSpeed).addClass('slide'); }); $aceMenu.on('mouseleave', 'li', function () { $(this).removeClass('menu-active'); $(this).children('ul.sub-menu').stop(true, true).slideUp($animationSpeed).removeClass('slide').removeAttr('style'); }); } } // Window resize on menu breakpoint function menuCollapse() { var w = $(window).innerWidth(); if (w <= $resizeWidth) { $aceMenu.find('li.menu-active').removeClass('menu-active'); $aceMenu.find('ul.slide').removeClass('slide').removeAttr('style'); $aceMenu.addClass('collapse hide-menu'); $aceMenu.attr('data-menu-style', ''); $('.menu-toggle').show(); } else { $aceMenu.attr('data-menu-style', $menuStyle); $aceMenu.removeClass('collapse hide-menu').removeAttr('style'); $('.menu-toggle').hide(); if ($aceMenu.attr('data-menu-style') == 'accordion') { $aceMenu.addClass('collapse'); } else { $aceMenu.find('li.menu-active').removeClass('menu-active'); $aceMenu.find('ul.slide').removeClass('slide').removeAttr('style'); } } // 每次resize后重新绑定正确的事件 setupMenuEvents(); } // 初始化时执行一次事件绑定 setupMenuEvents(); // 初始判断窗口状态 menuCollapse(); $(window).resize(function () { menuCollapse(); }); //ToggleBtn Click $('#menu-btn').click(function () { $aceMenu.slideToggle().toggleClass('hide-menu'); }); // Main function return this.each(function () { // 旧事件绑定逻辑已移至setupMenuEvents }); } })(jQuery);
关键改动说明
- 修复字符串比较问题:把
$resizeWidth转为整数,避免字符串与数字比较时的潜在错误。 - 统一事件管理:新增
setupMenuEvents函数,每次窗口resize或初始化时,先解绑所有旧事件,再根据当前菜单状态(是否折叠)绑定对应的鼠标或点击事件,彻底解决事件冲突。 - 阻止链接默认行为:在折叠模式的点击事件里添加
e.preventDefault(),避免点击菜单链接时的意外跳转干扰菜单动画。 - 优化状态重置逻辑:在
menuCollapse函数里,针对非accordion的展开视图,明确重置菜单状态,避免残留的active状态导致异常。
额外建议
- 测试时可以调整
resizeWidth的值(比如设为1024),适配更多平板横屏的宽度。 - 如果你的菜单链接需要跳转,可以在点击事件里判断当前点击的是菜单标题还是真正的链接,比如只有当链接包含子菜单(有
.arrow元素)时才阻止默认行为。
内容的提问来源于stack exchange,提问作者Lilit Tarposhian
相关产品推荐
相关产品推荐

