#javascript #html #jquery #arrow-functions
Вопрос:
У меня есть два uls в мега-подменю, и я пытаюсь улучшить их доступность. Я хочу, чтобы пользователь мог использовать клавиши со стрелками для перемещения между первыми двумя элементами в двух отдельных списках в одном контейнере.
До сих пор я могу заставить клавиши со стрелками перемещаться между первым и последним пунктом в одном списке, но не переходить в другой список.
//left and and right arrow navigation functionality
$('.someclass a').keydown(function(e){
// Listen for the up, down, left and right arrow keys, otherwise, end here
if ([37,38,39,40].indexOf(e.keyCode) == -1) {
return;
}
// Store the reference to our top level link
var link = $(this);
console.log(link);
switch(e.keyCode) {
case 37: // left arrow
// Make sure to stop event bubbling
e.preventDefault();
e.stopPropagation();
//This is the first item in the top level mega menu list
if(link.closest('ul').next('ul').prevAll('ul').first().length == 0) {
console.log(link.closest('ul'));
// Focus on the next first link in the submenu
link.parent('li').nextAll('li').last().find('a').first().focus();
} else {
// Focus on the previous first link in the submenu
link.parent('ul').prevAll('ul').first().find('a').first().focus();
}
break;
case 38: /// up arrow
// Find the nested element that acts as the menu
var dropdown = link.parent('li').find('.truist-secondary-menu');
// If there is a UL available, place focus on the first focusable element within
if(dropdown.length > 0){
e.preventDefault();
e.stopPropagation();
dropdown.find('a').filter(':visible').first().focus();
}
break;
case 39: // right arrow
// Make sure to stop event bubbling
e.preventDefault();
e.stopPropagation();
// This is the last item
if(link.closest('ul').nextAll('li').filter(':visible').first().length == 0) {
// Focus on the next first link in the submenu
link.parent('li').prevAll('li').last().find('a').first().focus();
} else {
// Focus on the previous first link in the submenu
link.parent('li').nextAll('li').first().find('a').first().focus();
}
break;
case 40: // down arrow
// Find the nested element that acts as the menu
var dropdown = link.parent('li').find('.menu');
// If there is a UL available, place focus on the first focusable element within
if(dropdown.length > 0){
// Make sure to stop event bubbling
e.preventDefault();
e.stopPropagation();
dropdown.find('a').filter(':visible').first().focus();
}
break;
}
});
HTML довольно длинный, но вот сокращенная версия и лучшее объяснение того, что я хочу сделать.
<h3>List Heading One</h3>
<ul class="someulclass">
<li class="someclass">
<a></a>//arrow key left from here
</li>
<li class="someclass">
<a></a>
</li>
<li class="someclass">
<a></a>
</li>
</ul>
<h3>List Heading Two</h3>
<ul class="someulclass">
<li class="someclass">
<a></a> // to here, arrow key right back the other way
</li>
<li class="someclass">
<a></a>
</li>
<li class="someclass">
<a></a>
</li>
</ul>
Ответ №1:
Наконец-то понял! Необходимо изменить .parent(‘li’) на .closest(‘ul’).
$('.someclass a').keydown(function(e){
// Listen for the up, down, left and right arrow keys, otherwise, end here
if ([37,38,39,40].indexOf(e.keyCode) == -1) {
return;
}
// Store the reference to our top level link
var link = $(this);
console.log(link);
switch(e.keyCode) {
case 37: // left arrow
// Make sure to stop event bubbling
e.preventDefault();
e.stopPropagation();
//This is the first item in the top level mega menu list
if(link.closest('div').next('div').prevAll('div').first().length == 0) {
console.log(link.closest('ul'));
// Focus on the next first link in the submenu
link.closest('ul').nextAll('ul').last().find('a').first().focus();
} else {
// Focus on the previous first link in the submenu
link.closest('ul').prevAll('ul').first().find('a').first().focus();
}
break;
case 39: // right arrow
// Make sure to stop event bubbling
e.preventDefault();
e.stopPropagation();
// This is the last item
if(link.closest('div').nextAll('div').filter(':visible').first().length == 0) {
// Focus on the next first link in the submenu
link.closest('ul').prevAll('ul').last().find('a').first().focus();
} else {
// Focus on the previous first link in the submenu
link.closest('ul').nextAll('ul').first().find('a').first().focus();
}
break;
}
});