我正在尝试为投资组合风格的网站创建一个可访问的导航菜单。当屏幕小于某个宽度(本演示为 768 像素)时,水平菜单导航消失并被“汉堡”取代。burger 的父 div 具有 JavaScript onclick 和 onkeydown 函数,因此当点击或点击 burger,或者键盘用户关注它并使用按空格键或 Enter 时,会从包含垂直导航菜单的一侧打开一个 div 'sidenav' .
但是,如果键盘用户继续切换,焦点会继续向下导航到导航后面的页面,就好像“sidenav”不存在一样,当切换最终到达 sidenav 顶部时,它遇到的第一个元素是关闭按钮和制表符关闭菜单,因此无法访问菜单项。
所以:问题1:当汉堡被按下时,如何触发焦点“跳转”到新打开的导航?
问题 2:如何使“关闭”按钮忽略制表符,仅使用空格键或回车键?
这是我的菜单的简化版本(您可能需要全屏查看水平菜单)。
/* detect keyboard users */
function handleFirstTab(e) {
if (e.keyCode === 9) { // the "I am a keyboard user" key
document.body.classList.add('user-is-tabbing');
window.removeEventListener('keydown', handleFirstTab);
}
}
window.addEventListener('keydown', handleFirstTab);
/* Open Sidenav
-------------------*/
function openNav() {
let element = document.querySelector('ul.menucontent');
if (element.classList.contains('menucontent')) {
element.classList.remove('menu-a');
element.classList.add('menu-b');
};
let element3 = document.querySelector('div.sidenav');
let element4 = document.querySelector('.closebtn');
if (element3.classList.contains('sidenav')) {
element3.style.width = "350px";
element4.style.visibility = "visible";
};
document.getElementById('vmenu').focus();
}
function closeNav() {
let element = document.querySelector('ul.menucontent');
if (element.classList.contains('menucontent')) {
element.classList.remove('menu-b');
element.classList.add('menu-a');
};
let element3 = document.querySelector('div.sidenav');
let element4 = document.querySelector('.closebtn');
if (element3.classList.contains('sidenav')) {
element3.style.width = "0";
element4.style.visibility = "hidden";
};
}
// Toggle content
for (const selector of [".toggle-btn",]) {
const toggleButtons = [...document.querySelectorAll(selector)];
for (const toggleButton of toggleButtons) {
toggleButton.addEventListener('click', () => {
toggleButtons.filter(b => b !== toggleButton).forEach(b => {
b.nextElementSibling.classList.remove('reveal-content');
});
toggleButton.nextElementSibling.classList.toggle('reveal-content');
});
};
}
for (const selectorTwo of [".close-btn",]) {
const closeButtons = [...document.querySelectorAll(selectorTwo)];
for (const closeButton of closeButtons) {
closeButton.addEventListener('click', () => {
closeButton.parentElement.classList.toggle('reveal-content');
});
};
}
body.user-is-tabbing button > a:focus {
border: none;
}
body:not(.user-is-tabbing) a:focus,
body:not(.user-is-tabbing) button:focus,
body:not(.user-is-tabbing) input:focus,
body:not(.user-is-tabbing) select:focus,
body:not(.user-is-tabbing) textarea:focus {
outline: none;
}
.container-fluid,
.container {
margin-right: auto;
margin-left: auto;
width: 100%;
}
.d-block
.d-none {
display: none;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 996;
top: 0;
left: 0;
background-color: #fff;
overflow-x: hidden;
transition: 0.5s;
padding: 1rem 0 0;
box-shadow: 0 2px 5px #acaaaa;
}
.trigram {
position: relative;
top: 0;
left: 0;
margin-bottom: 1rem;
padding: 0;
background: transparent;
z-index: 995;
width: 2rem;
}
.burger {
position: relative;
border-top: 0.15rem solid green;
border-bottom: 0.15rem solid green;
background: transparent;
height: 1.5rem;
width: 2rem;
}
.burger::after {
position: absolute;
content: "";
border-top: 0.15rem solid green;
top: 40%;
left: 0;
width: 2rem;
}
.sidemenu {
position: relative;
top: 5rem;
}
.mm ul {
list-style: none;
}
.mm li {
margin: 1rem 0;
padding: 0 0 0 1rem;
}
.mm .menucontent.menu-a {
display: none;
}
.mm .menucontent.menu-b {
display: flex;
display: -webkit-flex;
flex-direction: column;
justify-content: normal;
margin: 0 0 1rem;
padding: 0;
position: relative;
top: 0;
z-index: 997;
overflow-y: auto;
}
.closebtn {
border-bottom: none;
font-size: 2.25rem;
margin: 0;
position: absolute;
top: 2rem;
right: 2rem;
z-index: 998;
}
@media only screen and (min-width: 768px){
.d-none {
display: none;
}
.d-md-block {
display: block;
}
.trigram {
display: none;
}
.mm .menucontent.menu-a {
position: relative;
padding: 0;
margin: 0 auto;
white-space: nowrap;
display: flex;
}
.mm .menucontent.menu-a,
.mm .menucontent.menu-b {
flex-direction: row;
justify-content: center;
}
.mm li {
padding: 0 0.5rem;
}
.main-menu-container {
border-top: 2px solid green;
border-bottom: 2px solid green;
padding: 0.5rem 0;
margin: 1rem 0;
}
}
<div id="sidenav" class="sidenav">
<div id="closebtn" class="closebtn">
<a href="javascript:void(0)" onclick="closeNav()" onkeydown="closeNav()" role="button" tabindex="0" aria-label="close navigation">×</a>
</div>
<div id="vmenu" class="sidemenu d-md-none mm">
<nav aria-label="Main Navigation" class="menuouter ">
<ul class="menucontent menu-a" role="menubar">
<li class="item-101 default current active single top-level" role="none" tabindex="-1">
<a href="#" title="Side menu Home" class="icon-home">Side menu Home</a>
</li>
<li class="item-128 single" role="none" tabindex="-1">
<a href="#" title="Side menu page 2">Side menu page 2</a>
</li>
</ul>
</nav>
</div>
</div>
<div class="container-fluid menu-outer d-block d-md-none">
<div id="trigram" class="trigram" role="button" tabindex="0" aria-label="open navigation" aria-controls="sidenav" aria-haspopup="true" onclick="openNav()" onkeydown="openNav()">
<div class="burger" style="cursor:pointer" > </div>
</div>
</div>
<div class="container-fluid d-none d-md-block">
<div class="main-menu-container">
<div id="hmenu" class="row d-none d-md-block main-menu mm">
<nav aria-label="Main Navigation" class="menuouter ">
<ul class="menucontent menu-a" role="menubar">
<li class="item-101 default current active single top-level" role="none" tabindex="-1">
<a href="#" title="Horizontal menu Home" class="icon-home">Horizontal menu Home</a>
</li>
<li class="item-128 single" role="none" tabindex="-1">
<a href="#" title="Horizontal menu page 2">Horizontal menu page 2</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div>This is some text. It has a link in it: <a href="#">This is the first link</a></div>
<div>Here is some more text with more links. It has a link in it: <a href="#">This is the second link</a>. Integer mauris sem, convallis ut, consequat in, sollicitudin sed, leo.</div>
<div>Sed lacus velit, consequat in, ultricies sit amet, malesuada et, diam. Integer mauris sem, convallis ut, consequat in, sollicitudin sed, leo. <a href="#">This is the third link </a>Cras purus elit, hendrerit ut, egestas eget, sagittis at, nulla. Integer justo dui, faucibus dictum, convallis sodales, accumsan id, risus. Aenean risus. Vestibulum scelerisque placerat sem.</div>