点击汉堡图标显示导航后,focus()方法无法聚焦首个菜单项
移动端导航显示后焦点无法切换到第一个菜单项的问题解决
静态网站小屏幕场景下,主导航默认隐藏,点击汉堡图标后导航展开。需求是导航显示时,将焦点从汉堡按钮移到第一个菜单项上,但尝试了setTimeout、调用汉堡按钮blur()、调整tabindex、querySelector获取元素、硬编码role属性等方案,甚至排查了是否有逻辑被覆盖,都没效果。
相关代码
<div class="header__item header__logo"> <div class="header__icon header__icon--mobileTrigger"> <button class="hamburger hamburger--spin" type="button" aria-label="open menu"> <span class="hamburger-box"> <span class="hamburger-inner"></span> </span> </button> </div> </div> <div class="header__item header__nav" aria-label="main menu"> <nav role="navigation" class="nav__wrapper"> <div class="menu-header-menu-container"> <ul id="menu-header-menu" class="menu"> <li><a href="#started" id="menu-focus" tabindex="0">Let's get started</a></li> <li><a href="#solutions" aria-current="false">More solutions</a></li> </ul> </div> </nav> </div> <script> $(document).on("click", ".header__icon--mobileTrigger", function (e) { $(this).find(".hamburger").addClass("is-active").attr("aria-label", "close menu"); $(".header__nav").attr({ role:"dialog", "aria-modal":"true", tabindex:"-1" }); $("#menu-focus").focus(); }); document.addEventListener('focus', function() { console.log('focused: ', document.activeElement) }, true); </script>
解决思路及方案
1. 等待导航元素完全渲染后再设置焦点
导航通常通过CSS隐藏(比如display: none、visibility: hidden或高度过渡),如果在元素未完全显示时调用focus(),会直接失效。可以通过setTimeout延迟执行焦点设置,让浏览器先完成渲染:
$(document).on("click", ".header__icon--mobileTrigger", function (e) { $(this).find(".hamburger").addClass("is-active").attr("aria-label", "close menu"); $(".header__nav").attr({ role:"dialog", "aria-modal":"true", tabindex:"-1" }); // 延迟0ms让浏览器先处理渲染 setTimeout(() => { $("#menu-focus").focus(); }, 0); });
如果导航用了过渡动画,也可以监听transitionend事件,动画结束后再设置焦点。
2. 先强制汉堡按钮失焦,再设置目标焦点
点击汉堡按钮后,按钮可能会保留焦点,需要主动让它失焦,再切换到菜单项:
$(document).on("click", ".header__icon--mobileTrigger", function (e) { const hamburgerBtn = $(this).find(".hamburger"); hamburgerBtn.addClass("is-active").attr("aria-label", "close menu").blur(); // 主动失焦 $(".header__nav").attr({ role:"dialog", "aria-modal":"true", tabindex:"-1" }); $("#menu-focus").focus(); });
3. 验证目标元素是否可聚焦
先确认第一个菜单项在导航显示时处于可交互状态,再执行焦点设置:
$(document).on("click", ".header__icon--mobileTrigger", function (e) { $(this).find(".hamburger").addClass("is-active").attr("aria-label", "close menu"); $(".header__nav").attr({ role:"dialog", "aria-modal":"true", tabindex:"-1" }); const targetLink = document.getElementById('menu-focus'); // 检查元素是否已显示(offsetParent不为null说明元素可见) if (targetLink.offsetParent !== null) { targetLink.focus(); } });
4. 排查CSS干扰
检查#menu-focus及其父元素的CSS,确保没有pointer-events: none、user-select: none这类会阻止元素聚焦的属性。
可以通过你添加的focus监听事件,查看document.activeElement的输出,确认焦点最终落在哪个元素上,进一步定位问题。
内容的提问来源于stack exchange,提问作者Avalynn Circe
相关产品推荐
相关产品推荐

