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

菜单键盘导航异常:按下下键子菜单获焦点后突然关闭

解决菜单键盘导航时子菜单突然关闭的问题

我来帮你搞定这个问题!你遇到的子菜单突然关闭的核心原因是:当你按下下箭头把焦点从主菜单的li转移到子菜单元素时,主菜单的li会触发blur事件——而通常菜单的隐藏逻辑会绑定这个事件,导致子菜单还没来得及展示就被关掉了。

下面是修复后的完整方案,你可以根据自己的菜单HTML结构调整选择器:

核心修复思路

  1. 给主菜单的blur事件加延迟检查,确保子菜单元素有机会获取焦点后再决定是否关闭
  2. 完善键盘导航的逻辑,覆盖主菜单→子菜单、子菜单内上下切换、返回主菜单的场景
  3. 阻止箭头键的默认滚动行为,避免页面滚动影响菜单操作

完整代码示例

// 主菜单的显示/隐藏逻辑(带延迟检查)
$('.main-menu li').on('focus', function() {
  // 聚焦时显示子菜单
  $(this).find('.sub-menu').show();
}).on('blur', function() {
  var $currentItem = $(this);
  // 延迟100ms检查:如果子菜单里没有元素获得焦点,再关闭
  setTimeout(function() {
    if (!$currentItem.find('.sub-menu').has(':focus').length) {
      $currentItem.find('.sub-menu').hide();
    }
  }, 100);
});

// 全局键盘事件处理
$(document).on('keydown', function(e) {
  // 下箭头键(40):导航到下一个元素
  if (e.keyCode === 40) {
    e.preventDefault(); // 阻止页面默认滚动
    var $focused = $(':focus');
    
    // 如果当前焦点在主菜单,且有子菜单,聚焦子菜单第一个元素
    if ($focused.closest('.main-menu li').length && $focused.siblings('.sub-menu').length) {
      $focused.siblings('.sub-menu').find('a').first().focus();
    } 
    // 如果当前在子菜单,聚焦下一个元素(循环)
    else if ($focused.closest('.sub-menu').length) {
      var $nextItem = $focused.next('a');
      if ($nextItem.length) {
        $nextItem.focus();
      } else {
        $focused.closest('.sub-menu').find('a').first().focus();
      }
    }
  }
  // 上箭头键(38):导航到上一个元素
  else if (e.keyCode === 38) {
    e.preventDefault();
    var $focused = $(':focus');
    
    if ($focused.closest('.sub-menu').length) {
      var $prevItem = $focused.prev('a');
      // 如果有上一个元素,聚焦它;否则回到主菜单
      if ($prevItem.length) {
        $prevItem.focus();
      } else {
        $focused.closest('.sub-menu').siblings('a').focus();
      }
    }
  }
  // Shift+Tab键:从子菜单返回主菜单
  else if (e.shiftKey && e.keyCode === 9) {
    e.preventDefault();
    var $focused = $(':focus');
    
    if ($focused.closest('.sub-menu').length) {
      $focused.closest('.sub-menu').siblings('a').focus();
    }
  }
});

关键细节说明

  • 延迟检查blur事件:100ms的延迟足够让子菜单元素完成焦点获取,避免误关闭
  • 子菜单内循环导航:按下下箭头到子菜单最后一个元素时,会回到第一个元素;按下上箭头到第一个元素时,会返回主菜单
  • Shift+Tab的精准返回:确保从子菜单任何元素按Shift+Tab,都能回到对应的主菜单选项

你需要把代码里的.main-menu、.sub-menu替换成你实际菜单结构对应的类名或选择器,这样就能完美解决子菜单突然关闭的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:07:56