Skip to content

Instantly share code, notes, and snippets.

@simevidas
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save simevidas/26a36bea15e56b5c3fad to your computer and use it in GitHub Desktop.
Save simevidas/26a36bea15e56b5c3fad to your computer and use it in GitHub Desktop.
var $ = jQuery;
// Config = selectors for UL (tabs) and SECTION (panel) elements + which tab should be selected on init
var $list = $('.topbar__tabs');
var $sections = $('.tabbed-section');
var selected_index = 1;
// Caching the LI and A elements since they’ll be heavily used in the code
var $items = $list.children('li');
var $anchors = $list.find('a');
// The setup
$list.attr('role', 'tablist');
$items.attr('role', 'presentation');
$anchors.attr({
'role' : 'tab',
'tabindex' : '-1'
});
// Make each aria-controls correspond id of targeted section (re href)
$anchors.attr('aria-controls', function() {
return $(this).attr('href').substring(1);
});
// Make one tab selected by default and allow it focus
$items.eq(selected_index).children('a').attr({
'aria-selected' : 'true',
'tabindex' : '0'
});
// Make each section focusable and give it the tabpanel role
$sections.attr({
'role' : 'tabpanel'
});
// Make first child of each panel focusable programmatically
$sections.children(':first-child').attr({
'tabindex' : '0'
});
// Make all but the first section hidden (ARIA state and display CSS)
$sections.not( $sections.eq(selected_index) ).attr({
'aria-hidden' : 'true'
});
// Change focus between tabs with arrow keys
$anchors.on('keydown', function(e) {
// define current, previous and next (possible) tabs
var $original = $(this);
var $prev = $(this).parents('li').prev().children('[role="tab"]');
var $next = $(this).parents('li').next().children('[role="tab"]');
var $target;
// find the direction (prev or next)
switch (e.keyCode) {
case 37:
$target = $prev;
break;
case 39:
$target = $next;
break;
default:
$target = false;
break;
}
if ($target.length) {
$original.attr({
'tabindex' : '-1',
'aria-selected' : null
});
$target.attr({
'tabindex' : '0',
'aria-selected' : true
}).focus();
}
// Hide panels
$sections.attr('aria-hidden', 'true');
// Show panel which corresponds to target
$('#' + $(document.activeElement).attr('href').substring(1))
.attr('aria-hidden', null);
});
// Handle click on tab to show + focus tabpanel
$anchors.on('click', function(e) {
e.preventDefault();
// remove focusability [sic] and aria-selected
$anchors.attr({
'tabindex': '-1',
'aria-selected' : null
});
// replace above on clicked tab
$(this).attr({
'aria-selected' : true,
'tabindex' : '0'
});
// Hide panels
$sections.attr('aria-hidden', 'true');
// show corresponding panel
$('#' + $(this).attr('href').substring(1))
.attr('aria-hidden', null);
});
@simevidas
Copy link
Author

Source: http://heydonworks.com/practical_aria_examples/#tab-interface

I’ve refactored the jQuery code a bit. Most of the $(selector) calls have been replaced with cached references ($list, $sections, $anchors, etc.).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment