nav with submenu
by raviteja gunda
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Accessible Accordion Menu</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<nav>
<ul class="menu">
<li><a href="#">Home</a></li>
<li class="has-submenu">
<a href="#" aria-haspopup="true" aria-expanded="false">About</a>
<ul class="submenu">
<li><a href="#">Our Team</a></li>
<li><a href="#">Our History</a></li>
<li><a href="#">Mission & Values</a></li>
</ul>
</li>
<li><a href="#">Services</a></li>
<li class="has-submenu">
<a href="#" aria-haspopup="true" aria-expanded="false">Contact</a>
<ul class="submenu">
<li><a href="#">Email Us</a></li>
<li><a href="#">Visit Us</a></li>
</ul>
</li>
</ul>
</nav>
<script src="script.js"></script>
</body>
</html>
CSS
body {
font-family: Arial, sans-serif;
}
.menu {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
}
.menu > li {
position: relative;
margin-bottom: 1em;
}
.menu > li > a {
text-decoration: none;
padding: 1em;
display: block;
color: #333;
background-color: #f0f0f0;
}
.menu > li > a:focus {
background-color: #ccc;
}
.submenu {
list-style: none;
padding: 0;
margin: 0;
display: none;
background-color: #f0f0f0;
}
.submenu li a {
text-decoration: none;
padding: 1em;
display: block;
color: #333;
}
.submenu li a:focus {
background-color: #ccc;
}
.menu .has-submenu[aria-expanded="true"] > .submenu {
display: block;
}
/* Media query for mobile view */
@media (max-width: 600px) {
.menu {
flex-direction: column;
}
.submenu {
display: none;
}
.menu .has-submenu[aria-expanded="true"] > .submenu {
display: block;
}
}
JavaScript
document.addEventListener('DOMContentLoaded', function() {
const menuItems = document.querySelectorAll('.menu > .has-submenu > a');
menuItems.forEach(item => {
item.addEventListener('click', function(event) {
event.preventDefault();
const isExpanded = this.getAttribute('aria-expanded') === 'true';
this.setAttribute('aria-expanded', !isExpanded);
const submenu = this.nextElementSibling;
submenu.style.display = !isExpanded ? 'block' : 'none';
});
item.addEventListener('keydown', function(event) {
const submenuLinks = this.nextElementSibling.querySelectorAll('a');
const submenuFirstLink = submenuLinks[0];
const submenuLastLink = submenuLinks[submenuLinks.length - 1];
console.log(submenuLinks);
console.log(submenuFirstLink);
console.log(submenuLastLink);
if (event.key === 'Tab' && this.getAttribute('aria-expanded') === 'true') {
if (event.shiftKey) {
if (document.activeElement === this) {
submenuLastLink.focus();
event.preventDefault();
} else if (document.activeElement === submenuFirstLink) {
this.focus();
event.preventDefault();
}
} else {
if (document.activeElement === this) {
submenuFirstLink.focus();
event.preventDefault();
} else if (document.activeElement === submenuLastLink) {
this.focus();
event.preventDefault();
}
}
}
});
const submenuLinks = item.nextElementSibling.querySelectorAll('a');
submenuLinks.forEach((submenuItem, index) => {
submenuItem.addEventListener('keydown', function(event) {
if (event.key === 'Tab') {
if (!event.shiftKey && index === submenuLinks.length - 1) {
item.focus();
event.preventDefault();
} else if (event.shiftKey && index === 0) {
item.focus();
...