If multiple elements have the same tabindex , you then go in document order until you reach the last element with that tabindex . Then you move to the next lowest tabindex and the process continues. Finally, finish with those elements with a zero (or empty) tabindex .
A negative value (usually tabindex="-1" ) means that the element is not reachable via sequential keyboard navigation, but could be focused with JavaScript or visually by clicking with the mouse. It's mostly useful to create accessible widgets with JavaScript.
The only way to change this order is to reorder your HTML elements. tabindex itself can do 2 things: it sets the order of "focusable" elements. it makes element "focusable".
I've never implemented this, but I've looked into a similar problem, and here's what I would try.
First, I would see if you could simply fire a keypress
event for the Tab key on the element that currently has focus. There may be a different way of doing this for different browsers.
Referencing the jQuery implementation, you must:
Listening for Tab and Shift+Tab are probably well-covered elsewhere on the web, so I'll skip that part.
Knowing which elements are tab-able is trickier. Basically, an element is tab-able if it is focusable and does not have the attribute tabindex="-1"
set. So then we must ask which elements are focusable. The following elements are focusable:
input
, select
, textarea
, button
, and object
elements that aren't disabled.a
and area
elements that have an href
or have a numerical value for tabindex
set.tabindex
set.Furthermore, an element is focusable only if:
display: none
.visibility
is visible
. This means that the nearest ancestor to have visibility
set must have a value of visible
. If no ancestor has visibility
set, then the computed value is visible
.More details are in another Stack Overflow answer.
The tab order of elements in a document is controlled by the tabindex
attribute. If no value is set, the tabindex
is effectively 0
.
The tabindex
order for the document is: 1, 2, 3, …, 0.
Initially, when the body
element (or no element) has focus, the first element in the tab order is the lowest non-zero tabindex
. If multiple elements have the same tabindex
, you then go in document order until you reach the last element with that tabindex
. Then you move to the next lowest tabindex
and the process continues. Finally, finish with those elements with a zero (or empty) tabindex
.
Here's something I build for this purpose:
function focusNextElement () {
//add all elements we want to include in our selection
var focussableElements = 'a:not([disabled]), button:not([disabled]), input[type=text]:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])';
if (document.activeElement && document.activeElement.form) {
var focussable = Array.prototype.filter.call(document.activeElement.form.querySelectorAll(focussableElements),
function (element) {
//check for visibility while always include the current activeElement
return element.offsetWidth > 0 || element.offsetHeight > 0 || element === document.activeElement
});
var index = focussable.indexOf(document.activeElement);
if(index > -1) {
var nextElement = focussable[index + 1] || focussable[0];
nextElement.focus();
}
}
}
Without jquery:
First of all, on your tab-able elements, add class="tabable"
this will let us select them later.
(Do not forget the "." class selector prefix in the code below)
var lastTabIndex = 10;
function OnFocusOut()
{
var currentElement = $get(currentElementId); // ID set by OnFOcusIn
var curIndex = currentElement.tabIndex; //get current elements tab index
if(curIndex == lastTabIndex) { //if we are on the last tabindex, go back to the beginning
curIndex = 0;
}
var tabbables = document.querySelectorAll(".tabable"); //get all tabable elements
for(var i=0; i<tabbables.length; i++) { //loop through each element
if(tabbables[i].tabIndex == (curIndex+1)) { //check the tabindex to see if it's the element we want
tabbables[i].focus(); //if it's the one we want, focus it and exit the loop
break;
}
}
}
I created a simple jQuery plugin which does just this. It uses the ':tabbable' selector of jQuery UI to find the next 'tabbable' element and selects it.
Example usage:
// Simulate tab key when element is clicked
$('.myElement').bind('click', function(event){
$.tabNext();
return false;
});
The core of the answer lies on finding the next element:
function findNextTabStop(el) {
var universe = document.querySelectorAll('input, button, select, textarea, a[href]');
var list = Array.prototype.filter.call(universe, function(item) {return item.tabIndex >= "0"});
var index = list.indexOf(el);
return list[index + 1] || list[0];
}
Usage:
var nextEl = findNextTabStop(element);
nextEl.focus();
Notice I don't care about prioritizing tabIndex
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With