I've set up a very light jquery tab system for a website:
starting from this HTML code:
1
2
3
4
Styles CSS are based on ARIA attributes :
[aria-hidden=true] {
display: none;
}
and jQuery code will do the rest:
/* loading aria attribute on pates tabs */
$('.pates-tabs__list').attr('role', 'tablist'); // ul
$('.pates-tabs__item').attr('role', 'presentation'); // li
$('.pates-tabs__link').attr('role', 'tab'); // a
$('.pates-tabs__link').each(function() { // controls attribute
$this = $(this);
controls = '' + $this.attr('href');
controls = controls.replace('#','');
$this.attr('aria-controls', controls);
$this.attr('tabindex', '-1');
});
$('.pates-tabs__tabcontent').attr('role', 'tabpanel'); // contents
$('.pates-tabs__tabcontent').attr('aria-hidden', 'true'); // all hidden
$('.pates-tabs__tabcontent').each(function() { // label by link
$this = $(this);
labelledby = 'label_' + $this.attr('id');
$this.attr('aria-labelledby', labelledby);
});
// hash => select the good one
hash = window.location.hash;
hash = hash.replace('#','');
$('.pates-tabs__tabcontent').each(function() {
$this = $(this);
if ( hash == $this.attr('id') ){
selector = '#' + hash;
// affichage
$(selector).removeAttr('aria-hidden');
// selection menu
selector = '#label_' + hash;
$(selector).attr('aria-selected', 'true');
$(selector).attr('tabindex', '0');
return false; // on sort du each
}
});
// if no selected => select first
if ($('.pates-tabs__link[aria-selected]').length == 0) {
$('.pates-tabs__link:first').attr('aria-selected', 'true');
$('.pates-tabs__link:first').attr('tabindex', '0');
$('.pates-tabs__tabcontent:first').removeAttr('aria-hidden');
}
/* click on a link */
$('.pates-tabs__link').click(
function() {
$this = $(this);
// remove aria selected on all links + remove focusable
$('.pates-tabs__link').removeAttr('aria-selected');
$('.pates-tabs__link').attr('tabindex', '-1');
// add aria selected on $this + focusable
$this.attr('aria-selected', 'true');
$this.attr('tabindex', '0');
// add aria-hidden on all tabs
$('.pates-tabs__tabcontent').attr('aria-hidden', 'true');
// remove aria-hidden on tab linked
id_to_show = '#' + $this.attr('aria-controls');
$(id_to_show).removeAttr('aria-hidden');
return false;
}
);
$('body').on('keydown','.pates-tabs', function(event) {
// strike up or left in the tab
if (event.keyCode == 37 || event.keyCode == 38) {
// find previous tab
// if we are on first => activate last
$activated = $('.pates-tabs__link[aria-selected="true"]').parent();
if($activated.is('.pates-tabs__item:first-child')) {
$('.pates-tabs__item:last-child a').click().focus();
}
else { // else activate previous
$activated.prev().children('.pates-tabs__link').click().focus();
}
event.preventDefault();
}
// strike down or right in the tab
if (event.keyCode == 40 || event.keyCode == 39) {
// find next tab
// if we are on last => activate first
$activated = $('.pates-tabs__link[aria-selected="true"]').parent();
if($activated.is('.pates-tabs__item:last-child')) {
$('.pates-tabs__item:first-child a').click().focus();
}
else { // else activate next
$activated.next().children('.pates-tabs__link').click().focus();
}
event.preventDefault();
}
//event.stopPropagation();
//return false;
}
);
/*********************************************************************************************************/
There it is.