Introducing Focusability

Firefox(10y ago)

I just created a small library for seeing the elements that are focusable on your page. I've found that with accessibility, often the biggest blocker is that it's hard to surface your pages short-comings. Hopefully, this tool will help make it clear what will happen when your user starts tabbing around.

This works by finding the focusable elements, whether it be an element w/ a tabindex, an a, img, or other element which satisfy this predicate:

function focusable(element) {
var map,
mapName,
img,
nodeName = element.nodeName.toLowerCase(),
isTabIndexNotNaN = !isNaN($.attr(element, "tabindex"));
if ("area" === nodeName) {
map = element.parentNode;
mapName = map.name;
if (!element.href || !mapName || map.nodeName.toLowerCase() !== "map") {
return false;
}
img = $("img[usemap=#" + mapName + "]")[0];
return !!img && visible(img);
}
return (
(/input|select|textarea|button|object/.test(nodeName)
? !element.disabled
: "a" === nodeName
? element.href || isTabIndexNotNaN
: isTabIndexNotNaN) &&
// the element and all of its ancestors must be visible
visible(element)
);

function visible(element) {
return (
$.expr.filters.visible(element) &&
!$(element)
.parents()
.addBack()
.filter(function () {
return $.css(this, "visibility") === "hidden";
}).length
);
}
}
function focusable(element) {
var map,
mapName,
img,
nodeName = element.nodeName.toLowerCase(),
isTabIndexNotNaN = !isNaN($.attr(element, "tabindex"));
if ("area" === nodeName) {
map = element.parentNode;
mapName = map.name;
if (!element.href || !mapName || map.nodeName.toLowerCase() !== "map") {
return false;
}
img = $("img[usemap=#" + mapName + "]")[0];
return !!img && visible(img);
}
return (
(/input|select|textarea|button|object/.test(nodeName)
? !element.disabled
: "a" === nodeName
? element.href || isTabIndexNotNaN
: isTabIndexNotNaN) &&
// the element and all of its ancestors must be visible
visible(element)
);

function visible(element) {
return (
$.expr.filters.visible(element) &&
!$(element)
.parents()
.addBack()
.filter(function () {
return $.css(this, "visibility") === "hidden";
}).length
);
}
}

Introducing Focusability