javascript - Fokusera nästa element i tabbindex


Jag försöker flytta fokus till nästa element i tabbsekvensen baserat på det aktuella elementet som har fokus. Hittills har jag inte hittat något i mina sökningar.

function OnFocusOut()
{
    var currentElement = $get(currentElementId); // ID set by OnFocusIn 

    currentElementId = "";
    currentElement.nextElementByTabIndex.focus();
}

Självklart är nextElementByTabIndex nyckeln för att detta ska fungera. Hur hittar jag nästa element i fliksekvensen? Lösningen måste baseras på JScript och inte något som JQuery.

Svar #1

Jag har aldrig implementerat detta, men jag har undersökt ett liknande problem, och här är vad jag skulle försöka.

Med hänvisning till jQuery-implementeringen måste du:

  1. Lyssna efter Tab och Skift+Tab
  2. Vet vilka element som kan tabbifieras
  3. Förstå hur tabbordning fungerar

1. Lyssna efter Tab och Shift+Tab

Att lyssna efter Tab och Shift+Tab täcks nog väl på andra håll på webben, så jag hoppar över den delen.

2. Vet vilka element som kan tabbas

Att veta vilka element som kan tabbats är knepigare. I princip är ett element tabb-bart om det kan fokuseras och inte har attributet tabindex="-1" satt. Så då måste vi fråga vilka element som kan fokuseras. Följande element kan fokuseras:

  • input, select, textarea, button och object-element som inte är inaktiverade.
  • A och områdeselement som har ett HREF eller har ett numeriskt värde för tabindexmängden.
  • något element som har ett numeriskt värde för tabindex inställt.

Dessutom är ett element fokuserbart endast om:

  • Ingen av dess förfäder är display: none.
  • Det beräknade värdet av visibility är visible. Detta betyder att den närmaste förfadern som har visibility satt måste ha värdet visible. Om ingen förfader har visibility satt, är det beräknade värdet visible.

Fler detaljer finns i ett annat svar på Stack Overflow.

3. Förstå hur tabbordning fungerar

Tabulatorordningen för element i ett dokument styrs av tabindex-attributet. Om inget värde sätts är tabindexet i praktiken 0.

Ordningen för tabindex i dokumentet är: 1, 2, 3, …, 0.

Inledningsvis, när kroppselementet (eller inget element) har fokus, är det första elementet i tabbordningen det lägsta icke-noll tabindexet. Om flera element har samma tabindex går du sedan i dokumentordning tills du når det sista elementet med det tabindexet. Sedan går du till nästa lägsta tabindex och processen fortsätter. Slutligen, avsluta med dessa element med ett tabindex noll (eller tomt).

Svar #2

Här är något jag byggt för detta ändamål:

function focusNextElement() {
  //add all elements we want to include in our selection
  var focussableElements =
    'a:not([disabled]), button:not([disabled]), input[type=text]:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])';
  if (document.activeElement && document.activeElement.form) {
    var focussable = Array.prototype.filter.call(
      document.activeElement.form.querySelectorAll(focussableElements),
      function (element) {
        //check for visibility while always include the current activeElement
        return (
          element.offsetWidth > 0 ||
          element.offsetHeight > 0 ||
          element === document.activeElement
        );
      }
    );
    var index = focussable.indexOf(document.activeElement);
    if (index > -1) {
      var nextElement = focussable[index + 1] || focussable[0];
      nextElement.focus();
    }
  }
}

Funktioner:

  • Konfigurerbar mängd fokuserbara element
  • ingen jQuery behövs
  • fungerar i alla moderna webbläsare
  • snabb och lätt

Svar #3

Utan jquery: För det första, på dina tabbar- kapabla element, lägg till class="tabable" detta låter oss välja dem senare. (Glöm inte "." klassväljare-prefixet i koden nedan)

var lastTabIndex = 10;
function OnFocusOut()
{
    var currentElement = $get(currentElementId); // ID set by OnFOcusIn
    var curIndex = currentElement.tabIndex; //get current elements tab index
    if(curIndex == lastTabIndex) { //if we are on the last tabindex, go back to the beginning
        curIndex = 0;
    }
    var tabbables = document.querySelectorAll(".tabable"); //get all tabable elements
    for(var i=0; i<tabbables.length; i++) { //loop through each element
        if(tabbables[i].tabIndex == (curIndex+1)) { //check the tabindex to see if it's the element we want
            tabbables[i].focus(); //if it's the one we want, focus it and exit the loop
            break;
        }
    }
}

Svar #4

Jag skapade ett enkelt jQuery-plugin som gör precis detta. Det använder jQuery UI:s ':tabbable'-väljare för att hitta nästa 'tabbable'-element och väljer det.

Exempel på användning:

// Simulate tab key when element is clicked 
$('.myElement').bind('click', function(event){
    $.tabNext();
    return false;
});

Svar #5

Kärnan i svaret ligger i att hitta nästa element:

  function findNextTabStop(el) {
    var universe = document.querySelectorAll('input, button, select, textarea, a[href]');
    var list = Array.prototype.filter.call(universe, function(item) {return item.tabIndex >= "0"});
    var index = list.indexOf(el);
    return list[index + 1] || list[0];
  }

Användning:

var nextEl = findNextTabStop(element);
nextEl.focus();

Observera att jag inte bryr mig om att prioritera tabIndex.

Relaterade artiklar