I have a simple implementation on accessibility via keyboard input on a list of drop down menus, which I made using HTML/CSS and whose events are controlled via JS/jQuery.
The objective of accessibility via keyboard is like so:
- Navigate the drop down menu elements by pressing on the tab key.
- Press the down arrow key to open a focused menu.
- Within such menu, pressing the tab key will help you navigate through the menu elements.
- Within such menu, pressing the esc key will close the drop down menu.
- Once the menu is closed, maintain keyboard focus upon the representing parent element of the menu.
Here is the jsFiddle I made as an example of a fully fledged implementation.
The problem lies specifically in the jQuery code, the last statement is the one which is where I am trying to determine the solution to my problem (read below).
My problem: How do I make it so that when the esc key is pressed to close the drop down menu; I am back to the drop down menu parent element which I first used to access the drop down menu elements via the down arrow key? The reason for this is that, in my implementation, if we exit the drop down menu we are effectively asking the user to tab their way to the element they where on.
That is the unintended behavior I am trying to fix by trying (and failing) to set the focus to the parent element I just visited.
Any help is very appreciated!
HTML
<ul class="menu">
<li>
<a href="#">Menu Elem</a>
<div class="subMenu">
<ul>
<li>
<a href="#">Sub Menu Elem</a>
</li>
<li>
<a href="#">Sub Menu Elem</a>
</li>
<li>
<a href="#">Sub Menu Elem</a>
</li>
</ul>
</div>
</li>
<li>
<a href="#">Menu Elem</a>
<div class="subMenu">
<ul>
<li>
<a href="#">Sub Menu Elem</a>
</li>
<li>
<a href="#">Sub Menu Elem</a>
</li>
<li>
<a href="#">Sub Menu Elem</a>
</li>
</ul>
</div>
</li>
<li>
<a href="#">Menu Elem</a>
<div class="subMenu">
<ul>
<li>
<a href="#">Sub Menu Elem</a>
</li>
<li>
<a href="#">Sub Menu Elem</a>
</li>
<li>
<a href="#">Sub Menu Elem</a>
</li>
</ul>
</div>
</li>
</ul>
CSS
.menu > li {
display: inline-block;
text-align: center;
color: white;
background-color: orange;
width: 100px;
height: 70px;
position: fixed;
}
.menu > li:hover {
cursor: pointer;
}
.menu > :nth-child(1) {
left: 1px;
}
.menu > :nth-child(2){
left: 102px;
}
.menu > :nth-child(3){
left: 203px;
}
.menu > li > a {
line-height: 70px;
}
.menu > li > .subMenu {
display: none;
width: 200px;
margin-top: 1px;
outline: 1px solid black;
}
.menu > li > .subMenu > ul > li {
height: 100px;
background-color: green;
margin-left: -40px;
line-height: 100px;
}
.menu > li > .subMenu > ul > li:hover {
background-color: purple;
cursor: pointer;
}
a {
text-decoration: none;
color: white;
}
JS/jQuery
$(document).ready(function(){
var menuElem = $(".menu > li");
$(menuElem).hover(function(){
$(this).find(".subMenu").toggle();
});
$(menuElem).keydown(function(e) {
// down arrow key
if(e.keyCode === 40 && $(this).find(".subMenu").is(":hidden")){
$(this).find(".subMenu").toggle();
}
// esc key
else if(e.keyCode === 27 && $(this).find(".subMenu").is(":visible")){
$(this).find(".subMenu").toggle();
// ***** problematic code here *****
// Need to target the <a> element, or the <li> element, or the <div>, or the <ul> element, not sure which one will work.
// Currently: trying to get whichever element represents the selected menu, in the below case the anchor element
$(menuElem).eq($(this).index()).find("a").addClass("selected");
}
});
});
a
element, by using.focus()
– Philip