如何将TAB按键、鼠标点击与mouseenter、mouseleave事件关联实现下拉菜单?
问题根因
现有逻辑异常主要由以下3个核心问题导致:
- 类选择器拼写错误:
$itsNewFocusedItem.closest("drop")漏掉了类选择器前缀.,正确写法为.closest(".drop"),导致永远无法匹配到父级下拉菜单容器 - jQuery对象初始化错误:
$itsHoverMainMenu = {}初始化为普通对象而非空jQuery对象,后续$itsHoverMainMenu.length判断逻辑会出现异常 - 缺少子菜单区域判断:鼠标离开顶部菜单栏li后,没有判断新聚焦的元素是否属于当前展开的子菜单内部,点击子菜单项时误触发了菜单隐藏逻辑
修复后的完整代码
function getFocusedItem() { return $(document.activeElement); } function setupHoverOverMainMenu() { $(document).ready(function() { // 初始化为空jQuery对象而非普通对象 var $itsHoverMainMenu = $(), $itsNewMainMenu, $itsPrevFocusedItem, $itsNewFocusedItem; $("#menubar > li").on({ mouseenter: function(evt) { $itsPrevFocusedItem = getFocusedItem(); if ($itsPrevDropMenu.length > 0) { hideMenu($itsPrevDropMenu); } if ($(this).hasClass("drop")) { $itsHoverMainMenu = $(this).find(".aMenu").first(); showMenu($itsHoverMainMenu); } }, mouseleave: function(evt) { $itsNewFocusedItem = getFocusedItem(); // 新增判断:新聚焦元素是否属于当前展开的子菜单内部 const isFocusInCurrentSubmenu = $itsHoverMainMenu.length && $itsHoverMainMenu.has($itsNewFocusedItem).length > 0; // 如果点击了子菜单内的元素,直接保留当前菜单展开状态,不做隐藏操作 if (isFocusInCurrentSubmenu) { return; } if (($itsNewFocusedItem.length > 0) && ($itsNewFocusedItem[0] !== $itsPrevFocusedItem[0])) { // 修复类选择器拼写错误,添加.前缀 $itsNewMainMenu = $itsNewFocusedItem.closest(".drop").find(".aMenu").first(); if (($itsNewMainMenu.length > 0) && ($itsNewMainMenu[0] !== $itsPrevDropMenu[0])) { showMenu($itsNewMainMenu); } else { $itsNewMainMenu = getOtherMainMenu($itsNewFocusedItem); if (($itsNewMainMenu.length > 0) && ($itsNewMainMenu[0] !== $itsPrevDropMenu[0])) { showMenu($itsNewMainMenu); } } } else { if ($itsHoverMainMenu.length > 0) { hideMenu($itsHoverMainMenu); } if ($itsPrevDropMenu.length > 0) { showMenu($itsPrevDropMenu); } } } }); }); }
关键修改说明
- 修正了
.drop类选择器的拼写错误,确保可以正确匹配到父级下拉菜单容器 - 调整了
$itsHoverMainMenu的初始化类型为jQuery空对象,保证后续length判断逻辑正常 - 新增子菜单内聚焦判断逻辑:如果鼠标离开顶部菜单项时,当前聚焦的元素是在当前展开的子菜单内部,直接中断后续隐藏逻辑,保持子菜单展开状态
内容的提问来源于stack exchange,提问作者user16770432
相关产品推荐
相关产品推荐

