Introducing Focusability

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;
    }
}

19 Mar 2015