Reputation: 722
I want to be able to navigate through all the focusable elements on my webpage with the arrow key. So when the down-key is pressed the focus should shift to the focusable element beneath the current focussed element. You get the idea for the other arrow keys, when there is not a focusable element to shift to, the focus should remain the same.
This is what I got so far:
$(document).keydown(function(e){
if (e.keyCode == 37) { //left
var offset = $("*:focus").offset();
var allElements = $("#container").find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]');
var arr = jQuery.makeArray(allElements);
var topLeft = offset.left
var minus = topLeft;
var currentElement = $("*:focus");
for(var i = 0; i < arr.length; i++)
{
if ( (arr[i].offset().left < offset.left) // This doesn't work for some reason
&& ((offset.left - arr[i].offset().left) < minus))
{
currentElement = arr[i];
minus = offset.left - arr[i].offset().left;
topLeft = arr[i].offset().left;
}
currentElement.focus();
}
alert( "left pressed" );
return false;
}
// Other Keys
});
the idea was to get all the focus-able elements and than pick select the one that is suited for the arrow and shift focus.
I'm not able to get this code to work (it contains a error) and I'm not completly sure it will even work.
Thnx in advance
[EDIT]: I guess I was a little vague. I do not only want to go left and right, but also up and down.
Upvotes: 16
Views: 50191
Reputation: 1127
None of above solutions worked for me. This one is mine. It look difficult but it's accually real easy. Create array
of link and change focus using the array index
. (I needed up/down arrow so keycodes are different). It also works with dynamicly
added links (cause I needed it this way, that is why I use on
)
$('#links_container').on("keydown", ".link",
function(e)
{
//start - list of <a>
var flag = false;
var smallMeni = document.getElementById('links_container');
var allElements2 = smallMeni.getElementsByTagName('a'); //.link
//end
//start - key down
if (e.keyCode == 40)
{
for (var i=0;i<allElements2.length;i++)
{
if(flag == true){
flag = false
allElements2[i].focus();
//alert(i)
}
else
{
if ( document.activeElement === allElements2[i] )
{
//alert(i);
flag = true;
}
}
}
}
//end
//start - key up
if (e.keyCode == 38)
{
for (var i=0;i<allElements2.length;i++)
{
if ( document.activeElement === allElements2[i] )
{
if (i>0)
{
allElements2[i-1].focus();
}
}
}
}
//alert(i);
}
);
Upvotes: 0
Reputation: 41
This works great
$('p').each(function(index) {
$(this).attr('tabindex', index)
}).on('keyup', function(e) {
e.preventDefault;
if (e.keyCode == 39) {
$('[TabIndex="' + Number(Number($(this).attr('tabindex')) + 1) + '"]').focus();
}
if (e.keyCode == 37) {
$('[TabIndex="' + Number(Number($(this).attr('tabindex')) - 1) + '"]').focus();
}
});
Upvotes: 0
Reputation: 11
Implemented above by checking some articles and stack over flow links
jQuery.fn.elementAfter = function(other) {
for(i = 0; i < this.length - 1; i++) {
if (this[i] == other) {
return jQuery(this[i + 1]);
}
}
return jQuery;
} ;
jQuery.fn.elementBefore = function(other) {
if (this.length > 0) {
for(i = 1; i < this.length; i++) {
if (this[i] == other) {
return jQuery(this[i - 1]);
}
}
}
return jQuery;
};
https://jsfiddle.net/bkLnq5js/79/
Upvotes: 0
Reputation: 9847
What I would do is much simpler. Just add a common class among the objects who should have this functionality (f.ex. "move") and use:
$(document).keydown(
function(e)
{
if (e.keyCode == 39) {
$(".move:focus").next().focus();
}
if (e.keyCode == 37) {
$(".move:focus").prev().focus();
}
}
);
See example: http://jsfiddle.net/uJ4PJ/
This code is much simpler and hopefully has all the functionality you need.
Just make sure the controls are in the correct order or this won't work properly.
Upvotes: 33
Reputation: 39
After much trial and error, I developed this code that works :
function navigate(origin, sens) {
var inputs = $('#form').find('input:enabled');
var index = inputs.index(origin);
index += sens;
if (index < 0) {
index = inputs.length - 1;
}
if (index > inputs.length - 1) {
index = 0;
}
inputs.eq(index).focus();
}
$('input').keydown(function(e) {
if (e.keyCode==37) {
navigate(e.target, -1);
}
if (e.keyCode==39) {
navigate(e.target, 1);
}
});
right arrow acts as tab
left arrow acts as shift tab
Upvotes: 3
Reputation: 328
Preview - http://jsfiddle.net/FehKh/ ;)
html:
<a href='jqwja' class="focusable">jajaj</a>
<a href='jjaasd' class="focusable focused">jajasdaaj</a>
<a href='jjqwea' class="focusable">jajaacasj</a>
<input value='iddqd' name="DoomII" class="focusable" />
js:
// init
$('.focused').focus();
// actual code
$(document).keydown(function(e){
if (e.keyCode == 37) { // left
if($('.focused').prev('.focusable').length)
$('.focused').removeClass('focused').prev('.focusable').focus().addClass('focused');
}
if (e.keyCode == 39) { // right
if($('.focused').next('.focusable').length)
$('.focused').removeClass('focused').next('.focusable').focus().addClass('focused');
}
});
Upvotes: 2