javascript - Hidden Div Tab-through (accessibility) -


i have section have hidden divs being displayed on click. trying achieve accessibility compliance if tab through , open 1 of sections tab through inner content of section , return left off initially.

eg. if tab through , open section 1 able tab through inner contents of section 1 , after go button opens section 2, , forth...

i have created fiddle html / script https://jsfiddle.net/rjvw915r/10/

html example:

<div id="dropdown-menus">   <div id="section1-drop" class="drop-section hidden-panel">     <a href="#">link 1</a>     <a href="#">link 2</a>   </div>    <div id="section2-drop" class="drop-section hidden-panel">     <a href="#">link 1</a>     <a href="#">link 2</a>   </div> </div>  <ul id="dropdown-links" class="menu main-tabs">   <li>     <a class="panel-btn"         href="javascript:dropmenu('section1');"         id="drop-link-section1">section 1</a>   </li>   <li>     <a class="panel-btn"         href="javascript:dropmenu('section2');"         id="drop-link-section2">section 2</a>   </li> </ul> 

javascript:

function dropmenu(menusection) {     if ( !($('#dropdown-menus #' + menusection + '-drop').is(':hidden')) ) {          // select panel open. closes panel.         $('#dropdown-menus #' + menusection + '-drop').slideup(500);         $('#dropdown-menus #' + menusection + '-drop').removeclass('active');         $('a#drop-link-' + menusection).removeclass('active');          // scroll top of buttons.         var aid = $("#dropdown-links");         $('html,body').animate({scrolltop: aid.offset().top-480},400,function(){});      } else if ( $('#dropdown-menus .drop-section').hasclass('active')                  && $('#dropdown-menus #' + menusection + '-drop').is(':hidden') ) {          // panel open.          // closes open panel , opens selected panel.         $('.menu a.active').removeclass('active');         $('#dropdown-menus .active').slideup(500,function(){             $('#dropdown-menus #' + menusection + '-drop').slidedown(500);             $('#dropdown-menus #' + menusection + '-drop').addclass('active');             $('a#drop-link-' + menusection).addclass('active');         }).removeclass('active');          // scroll top of panel.         var aid = $("#dropdown-menus");         $('html,body').animate({scrolltop: aid.offset().top-155},400,function(){});      } else {          // no panel open. opens selected panel.         $('#dropdown-menus #' + menusection + '-drop').slidedown(500);         $('#dropdown-menus #' + menusection + '-drop').addclass('active');         $('a#drop-link-' + menusection).addclass('active');          // scroll top of panel.         var aid = $("#dropdown-menus");         $('html,body').animate({scrolltop: aid.offset().top-155},400,function(){});     } } 

thank you!

you can use click event perform javascript actions when link clicked or enter pressed.

<div id="dropdown-menus">   <div id="section1-drop" class="drop-section hidden-panel">     <a href="#">link 1</a>     <a href="#">link 2</a>   </div>    <div id="section2-drop" class="drop-section hidden-panel">     <a href="#">link 3</a>     <a href="#">link 4</a>   </div> </div>  <ul id="dropdown-links" class="menu main-tabs">   <li>     <a class="panel-btn"         data-section="section1-drop"        id="drop-link-section1">section 1</a>   </li>   <li>     <a class="panel-btn"         data-section="section2-drop"        id="drop-link-section2">section 2</a>   </li> </ul> 

above, have removed href attribute , added data-section element specifies section link activates. more semantic , readable, , can set our handlers within jquery.

define focus handler:

// setup focus handler root links $('.panel-btn').on('click', function(e) {     var link = $(this);     var section = link.attr('data-section');      // pass in current link , section name dropmenu     dropmenu($(this), section); }); 

i've cleaned drop menu function bit clarify what's happening

function dropmenu(link, menusection) {    // section specified menusection id   var section = $('#' + menusection);    // open section checking active class   var opensection = $('#dropdown-menus').find('.drop-section.active');    // anonymous function activating section , focussing    // first link within section   var showsection = function() {     // slide section view     section.slidedown(500).addclass('active');      // focus first link in section.     section.find('a').first().focus();   }    // if there section open, want slide first,   // call showsection when has completed.    if(opensection.length > 0) {      // if open section 1 clicked, want     // close section rather open     if(opensecion[0] === section[0]) {         opensection.slideup(500).removeclass('active');     }     else {         opensection.slideup(500, showsection).removeclass('active');     }   }    // otherwise, can show section straight away.   else {     showsection();   } } 

this pretty standard, need handle moving between sections expect happen natively using tab key. problem since 'drop sections' above root links, tabbing last link in drop section take section 1 since next tabbable element in document. prevent this, need work around of default functionality , implement our own.

first, you'll need configure keydown handler catch tabbing before happens

// setup keydown handler handle tabbing on section links $('.drop-section').on('keydown', 'a', function(e) {   if(e.keycode === tab_key) {     var link = $(this);      // flag determins whether prevent default tab behaviour     var preventdef = false;      // travel previous link on shift + tab     if(e.shiftkey) {       preventdef = travelprevious(link);     }      // travel next link on tab     else {       preventdef = travelnext(link);     }      // prevent default focus behaviour     if(preventdef) {       e.preventdefault();     }   } }); 

then need functions handle next tab, , previous tab

// handles travelling next link function travelnext(link) {   var next = link.next();    if(next.length > 0) {     // continue default behaviour of moving next link     return false;   }    // drop section parent id   var parentid = link.parents('.drop-section').attr('id');    // root link data-section attribute matches parent id   var rootlink = $('.panel-btn[data-section=' + parentid + ']').parent();    // next root link move to.   var nextlink = rootlink.next().find('a');    // focus on next root link, fire dropmenu    // next section.   nextlink.focus();    // prevent default behaviour   return true; }  function travelprevious(link) {   var prev = link.prev();    if(prev.length > 0) {     // continue default behaviour of moving previous link     return false;   }    // drop section parent id   var parentid = link.parents('.drop-section').attr('id');    // li container root link data-section attribute matches parent id   var rootlink = $('.panel-btn[data-section=' + parentid + ']').parent();    // previous root link move to.   var prevlink = rootlink.prev().find('a');    // focus on previous root link, fire dropmenu    // previous section.   prevlink.focus();    // prevent default behaviour   return true; } 

this still not complete solution because not handle reaching end or beginning of sections. should start , believe answers first question. if other questions this, should ask them seperately.

here fiddle example https://jsfiddle.net/rjvw915r/17/

update

if links contained in non-standard way within drop-section, method above won't quite work, uses next , prev functions direct siblings. if each a tag contained in div or li wrapper, have no direct siblings.

we can work around looking known parent element, , finding siblings via selector. in keydown function, add additional code retrieve these elements, , pass them travel functions.

$('.drop-section').on('keydown', 'a', function(e) {     if(e.keycode === tab_key) {         var link = $(this);          // retrieve available links within parent.         var linkcollection = link.parents('.drop-section').find('a');          ... 

in each of travel functions pass these links in

preventdef = travelprevious(link, linkcollection);  ...   preventdef = travelnext(link, linkcollection); 

by finding index of current link, can ascertain whether has siblings before or after it.

in travelnext function check see if there links after it

// find current link sits within collection var linkindex = linkcollection.index(link); var nextindex = linkindex + 1;  if(nextindex < linkcollection.length) {   // continue default behaviour of moving next link.   return false; } 

in travelprevious function check see if there links before it

// find current link sits within collection var linkindex = linkcollection.index(link); var nextindex = linkindex - 1;  if(nextindex >= 0) {   // continue default behaviour of moving previous link   return false; } 

see updated fiddle https://jsfiddle.net/rjvw915r/18/


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

android - Keyboard hides my half of edit-text and button below it even in scroll view -

css - Make div keyboard-scrollable in jQuery Mobile? -