使用原生JavaScript解决焦点下回车触发多个EventListener冲突问题
问题根源
你将两个Enter键监听事件直接绑定到了全局document对象上,且没有对触发事件的目标元素做校验,只要页面任意位置触发Enter键的keyup事件,就会同时执行两个切换逻辑,和当前聚焦元素无关,自然会出现误触发的问题。
解决方案
核心修改点:
- 键盘事件中增加目标元素判断,只有当前触发事件的元素是对应切换按钮时,才执行切换逻辑
- 替换已废弃的
keyCode判断为标准的event.key属性 - 补充无障碍属性,优化屏幕阅读器适配
修改后代码
HTML
<div class="search-toggle" tabindex="0" role="button" aria-expanded="false"> <span>Toggle Search</span> </div> <div class="search-form"> <span>Test Form</span> </div> <div class="toggle" tabindex="0" role="button" aria-expanded="false"> <span>Toggle Menu</span> </div> <nav class="nav"> <ul> <li><a href="#">Test</a></li> <li><a href="#">Test</a></li> <li><a href="#">Test</a></li> </ul> </nav>
JS
/* Search */ let searchToggle = document.querySelector('.search-toggle'), searchForm = document.querySelector('.search-form'); function searchClick(event) { event.stopPropagation(); let toggled = searchToggle.contains(event.target); if (toggled) { searchForm.classList.add('show-search-form'); searchToggle.setAttribute('aria-expanded', 'true') } else if (!event.target.closest('.show-search-form')) { searchForm.classList.remove('show-search-form'); searchToggle.setAttribute('aria-expanded', 'false') } } function searchFocus(event) { // 仅当触发事件的元素是搜索切换按钮、且按下的是Enter时执行逻辑 if (event.target === searchToggle && event.key === 'Enter') { event.stopPropagation(); searchToggle.click(); } } document.addEventListener('click', searchClick, false); document.addEventListener('keyup', searchFocus, false); /* Navigation */ let navToggle = document.querySelector('.toggle'), nav = document.querySelector('.nav'); navToggle.addEventListener('click', () => { const isExpanded = navToggle.getAttribute('aria-expanded') === 'true' nav.classList.toggle('toggle-menu'); navToggle.setAttribute('aria-expanded', isExpanded ? 'false' : 'true') }); function navFocus(event) { // 仅当触发事件的元素是导航切换按钮、且按下的是Enter时执行逻辑 if (event.target === navToggle && event.key === 'Enter') { event.stopPropagation(); navToggle.click(); } } document.addEventListener('keyup', navFocus, false);
CSS部分无需修改,保留原有代码即可。
内容的提问来源于stack exchange,提问作者thx1138
相关产品推荐
相关产品推荐

