You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ace Responsive Menu平板展开视图点击快速上滑问题求助

Fix for Ace Responsive Menu's Tablet Expanded View Glitch

我帮你找到了问题所在!这个菜单在平板展开视图(窗口宽度大于设置的resizeWidth但设备是平板)里点击菜单快速上滑的问题,根源是事件绑定和解绑不彻底,以及窗口 resize 时的状态判断逻辑有漏洞。

问题分析

  1. 当窗口从小于resizeWidth切换到大于resizeWidth时,原代码虽然移除了collapse类,但没有彻底解绑点击事件,也没有重新正确绑定鼠标事件,导致鼠标事件和点击事件冲突,触发了意外的菜单收起行为。
  2. 另外,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);

关键改动说明

  1. 修复字符串比较问题:把$resizeWidth转为整数,避免字符串与数字比较时的潜在错误。
  2. 统一事件管理:新增setupMenuEvents函数,每次窗口resize或初始化时,先解绑所有旧事件,再根据当前菜单状态(是否折叠)绑定对应的鼠标或点击事件,彻底解决事件冲突。
  3. 阻止链接默认行为:在折叠模式的点击事件里添加e.preventDefault(),避免点击菜单链接时的意外跳转干扰菜单动画。
  4. 优化状态重置逻辑:在menuCollapse函数里,针对非accordion的展开视图,明确重置菜单状态,避免残留的active状态导致异常。

额外建议

  • 测试时可以调整resizeWidth的值(比如设为1024),适配更多平板横屏的宽度。
  • 如果你的菜单链接需要跳转,可以在点击事件里判断当前点击的是菜单标题还是真正的链接,比如只有当链接包含子菜单(有.arrow元素)时才阻止默认行为。

内容的提问来源于stack exchange,提问作者Lilit Tarposhian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:51:06