I'm stuck while implementing drop down for each individual list item on focus/hover on any of them, now on hovering over any single list item all dropdowns are getting displayed.
This is my pen: https://codepen.io/apeandme/pen/GRZOxJQ
and the JS:
// main navigation interaction
'use strict';
var navbar;
var triggerContainer;
var triggerLink;
var toggleButton;
var lastMenuItem;
var mouseOutTimer; // timer used to delay hiding of menu after mouse leaves
var mouseOutHideDelay = 0; // time (in ms) before menu is closed after mouse leaves
var menuVisible = false;
var i = 0;
window.addEventListener('DOMContentLoaded', function(e) {
navbar = document.querySelector('nav');
triggerContainer = document.querySelectorAll('nav > ul > li.with-dd');
triggerLink = document.querySelectorAll('nav > ul > li.with-dd > a');
toggleButton = document.querySelectorAll('nav > ul > li.with-dd > .toggle-button');
lastMenuItem = document.querySelectorAll('nav > ul > li.with-dd > ul > li:last-of-type > a');
// Show the menu on mouse hover of the trigger
triggerContainer.forEach(item => {
item.addEventListener('mouseover', function(e) {
showMenu();
clearTimeout(mouseOutTimer);
});
});
// Hide the menu when mouse hover leaves both the trigger and menu fly-out, but only after a short delay to help people jerky mouse movements (like those using head/eye trackers)
triggerContainer.forEach(item => {
item.addEventListener('mouseout', function(e) {
mouseOutTimer = setTimeout(function() {
hideMenu();
}, mouseOutHideDelay);
});
});
// Hide the menu when the user tabs out of it
triggerContainer.forEach(item => {
item.addEventListener('keydown', triggerKeydownHandler);
});
// Toggle the menu when the trigger is activated
toggleButton.forEach(item => {
item.addEventListener('click', toggleMenu);
});
// Close the menu when the user activates something outside the navbar.
document.body.addEventListener('click', handleBodyClick);
});
/**
Menu visibility
**/
function showMenu() {
triggerLink.forEach(item => {
item.setAttribute('aria-expanded', true);
});
toggleButton.forEach(item => {
item.setAttribute('aria-expanded', true);
});
menuVisible = true;
}
function hideMenu() {
triggerLink.forEach(item => {
item.setAttribute('aria-expanded', false);
});
toggleButton.forEach(item => {
item.setAttribute('aria-expanded', false);
});
menuVisible = false;
}
function toggleMenu() {
if (menuVisible) {
hideMenu();
} else {
showMenu();
}
}
/**
Event handlers
*/
function handleBodyClick(e) {
if (!navbar.contains(e.target)) {
hideMenu();
}
}
function triggerKeydownHandler(e) {
// Hide the menu a keyboard user tabs out of it or presses Escape
if ((e.key === 'Tab' && !e.shiftKey && e.target === lastMenuItem) || e.key == 'Escape') {
hideMenu();
// Move focus back to the menu toggle button if Escape was pressed
if (e.key == 'Escape') {
toggleButton.focus();
}
}
}
Instead of opening all the dropdowns at once when one is hovered, you need to pass the 'hover' event to the function, in order to know which one of the triggers were hovered :