vendredi 4 septembre 2020

Web accessible navigation

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();
    }
  }
}



Aucun commentaire:

Enregistrer un commentaire