Last active
August 29, 2015 14:12
-
-
Save simevidas/26a36bea15e56b5c3fad to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.).