Reputation: 1543
I have a sidebar div and a content div layout. I am trying to make it arrow keys navigable.
Sidebar div
The sidebar div has vertical stacked menus, so it should be able to accept arrow up and arrow down events to move between each menu link and load content in the content div accordingly. Arrow right should navigate to the content div first element.
Content div
The content div is a flex container which loads image thumbnails in two rows. The arrow keys should be able to navigate between those. The left arrow key should again move focus to Sidebar div if the current focus is on the first element of content div.
I have this code in sidebar.js right now -
myClass.renderUI = function(data) {
var sidebar = $('#sidebar-menu');
html = template(data);
sidebar.append(html);
var arr = sidebar.find('li');
for (var i = 0; i < arr.length; i++) {
menu_rows.push($(arr[i]));
}
$('#sidebar-menu').find('li')[0].focus();
$("#sidebar-menu").find('li:first').addClass('active')
$("#movie-list").find('li:first').addClass('movie-active')
$('#navbar').find('li').each(function(item) {
$(item).keydown(function(e) {
handleKeyEvents(e, this);
});
})
};
function handleKeyEvents(e, currentElem) {
switch(e.which) {
case 37:
break;
case 38:
makeMenuActive(currentElem);
break;
case 39:
break;
case 40:
makeMenuActive(currentElem);
break;
default:
return;
}
e.preventDefault();
}
function makeMenuActive(currentElem) {
var url = currentElem.nextElementSibling.dataset.url;
$('.active').removeClass('active').next('li').addClass('active');
window.location.hash = url;
}
I am able to change the focus between menu links on the sidebar right now, and the keydown event only works when moving from first to second. Is there a way to bind keydown events on all the li elements (which is inefficient). Can't we use event delegation and add a keydown event on the parent div?
Also, how do I handle the arrow key navigation between the sidebar div and the content div?
Thanks in advance.
Upvotes: 0
Views: 3220
Reputation: 381
Yeah, delegation is the way to go. Attach the listener to the document object and check the focused element:
$(document).keydown(function (e) {
if (e.which === 38) {
if ($(':focus').index() === 0) {
// checks if focused item is first child of parent
}
}
});
UPDATE
Your images will need to be in anchor link tags because <li>
elements don't get the focus pseudo class. See the jsfiddle:
https://jsfiddle.net/91ahhmwm/1/
Upvotes: 1