Skip to content

Instantly share code, notes, and snippets.

@rbrum
Last active January 29, 2019 18:48
Show Gist options
  • Save rbrum/a36866259ca27ae910c90825a8166e0c to your computer and use it in GitHub Desktop.
Save rbrum/a36866259ca27ae910c90825a8166e0c to your computer and use it in GitHub Desktop.
(function ($) {
/**
* jQuery extension: Add support for :tabbable and :focusable pseudo-classes
*/
$.extend($.expr[':'], {
data: $.expr.createPseudo
? // creating pseudo's supported?
$.expr.createPseudo(function(dataName) {
return function(elem) {
return !!$.data(elem, dataName);
};
})
: // otherwise (supports jQuery <1.8)
function(elem, i, match) {
return !!$.data(elem, match[3]);
},
focusable: function(element) {
return focusable(element, !isNaN($.attr(element, 'tabindex')));
},
tabbable: function(element) {
var tabIndex = $.attr(element, 'tabindex'),
isTabIndexNaN = isNaN(tabIndex);
return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN);
}
});
/**
* focussable() function, taken from jQuery UI Core
* @param element
* @returns {*}
*/
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;
}
}
})(window.jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment