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

JS与CSS实现的无障碍下拉菜单点击菜单项后无法自动收起问题求助

解决方案

问题根因

你的站点是无刷新导航,点击子菜单项后页面不会重载,自然没法通过刷新重置菜单状态;且现有代码仅监听了带下拉的父级li的交互,没有针对子菜单项点击的关闭逻辑,所以才会出现菜单无法自动消失的问题。另外原代码中e.keyCode === 9 | e.type === 'mouseover'使用了按位或|,属于逻辑错误,需要改成逻辑或||。

修复步骤

  1. 新增子菜单项点击事件监听,点击后关闭所有已展开的下拉菜单,同时清除父级的js-openSubMenu状态
  2. 新增点击页面空白区域关闭所有下拉菜单的逻辑,提升交互体验
  3. 给父级li的点击事件添加阻止冒泡逻辑,避免点击父级展开菜单后被document的点击事件立即关闭

完整修改后的JS代码

$(document).ready(function() {
    // Remove no-js class
    $('html').removeClass('no-js');

    $('#toggleMenu').on('click', function() {
        if ( $(this).hasClass('js-open') ) {
            $('#nav > ul > li:not(#toggleMenu)').removeClass('js-showElement');
            $(this).removeClass('js-open');
            $(this).attr('aria-expanded', false);
        } else {
            $('#nav > ul > li:not(#toggleMenu)').addClass('js-showElement');
            $(this).addClass('js-open');
            $(this).attr('aria-expanded', true);
        }
        return false; 
    })

    // Add plus mark to li that have a sub menu
    $('nav ul li:has("ul") > a').append('<span class="fa fa-caret-down"></span>');

    // 新增:子菜单项点击关闭所有下拉
    $('nav li ul li a').on('click', function() {
        // 重置所有已展开的下拉菜单状态
        $('nav ul li:has("ul")').each(function() {
            $(this).children('a').removeClass('js-openSubMenu');
            $(this).children('ul').removeClass('js-showElement').addClass('js-hideElement');
        });
        // 此处可插入你自己的无刷新加载页面逻辑
    });

    // 新增:点击页面其他区域关闭所有下拉
    $(document).on('click', function(e) {
        if (!$(e.target).closest('nav').length) {
            $('nav ul li:has("ul")').each(function() {
                $(this).children('a').removeClass('js-openSubMenu');
                $(this).children('ul').removeClass('js-showElement').addClass('js-hideElement');
            });
        }
    });

    // sub menu
    // ------------------------
    // When interacting with a li that has a sub menu
    $('nav ul li:has("ul")').on('mouseover keyup click mouseleave', function(e) {
        // 阻止事件冒泡到document,避免点击父级展开后立即关闭
        e.stopPropagation();
        console.log("test")
        // If either -
        // tabbing into the li that has a sub menu
        // hovering over the li that has a sub menu
        if ( e.keyCode === 9 || e.type === 'mouseover' ) {
            // Show sub menu
            $(this).children('ul').removeClass('js-hideElement');
            $(this).children('ul').addClass('js-showElement');
        }
        // If mouse leaves li that has sub menu
        if ( e.type === 'mouseleave' ) {
            // hide sub menu
            $(this).children('ul').removeClass('js-showElement');
            $(this).children('ul').addClass('js-hideElement');
        }
        // If clicking on li that has a sub menu
        if ( e.type === 'click' ) {
            // If sub menu is already open
            if ( $(this).children('a').hasClass('js-openSubMenu') ) {
                // remove Open class
                $(this).children('a').removeClass('js-openSubMenu');
                // Hide sub menu
                $(this).children('ul').removeClass('js-showElement');
                $(this).children('ul').addClass('js-hideElement');
            // If sub menu is closed
            } else {
                // add Open class
                $(this).children('a').addClass('js-openSubMenu');
                // Show sub menu
                $(this).children('ul').removeClass('js-hideElement');
                $(this).children('ul').addClass('js-showElement');
            }
        } // end click event
    });

    // Tabbing through Levels of sub menu
    // ------------------------
    // If key is pressed while on the last link in a sub menu
    $('li > ul > li:last-child > a').on('keydown', function(e) {
        // If tabbing out of the last link in a sub menu AND not tabbing into another sub menu
        if ( (e.keyCode == 9) && $(this).parent('li').children('ul').length == 0 ) {
            // Close this sub menu
            $(this).parent('li').parent('ul').removeClass('js-showElement');
            $(this).parent('li').parent('ul').addClass('js-hideElement');
            // If tabbing out of a third level sub menu and there are no other links in the parent (level 2) sub menu
            if ( $(this).parent('li').parent('ul').parent('li').parent('ul').parent('li').children('ul').length > 0 
                && $(this).parent('li').parent('ul').parent('li').is(':last-child') ) {
                // Close the parent sub menu (level 2) as well
                $(this).parent('li').parent('ul').parent('li').parent('ul').removeClass('js-showElement');
                $(this).parent('li').parent('ul').parent('li').parent('ul').addClass('js-hideElement');
            }
        }
    })
})

// Focus on keyboard only
document.addEventListener("keydown", function(){
    document.documentElement.classList.remove('as-mouseuser');
    document.documentElement.classList.add('as-keyboarduser');
});
document.addEventListener("mousedown", function(){
    document.documentElement.classList.remove('as-keyboarduser');
    document.documentElement.classList.add('as-mouseuser');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 08:24:06