133 votes

Mettre en évidence l'élément suivant dans l'index des onglets

J'essaie de déplacer le focus vers l'élément suivant dans la séquence d'onglets en fonction de l'élément actuel qui a le focus. Jusqu'à présent, je n'ai rien trouvé dans mes recherches.

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

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

Bien sûr, le nextElementByTabIndex est l'élément clé pour que cela fonctionne. Comment trouver l'élément suivant dans la séquence d'onglets ? La solution doit être basée sur JScript et non sur quelque chose comme JQuery.

3 votes

Pourquoi avez-vous cette ligne currentElementId = ""; ?

1 votes

Je ne pense pas que les navigateurs exposent les informations sur l'ordre des onglets - et l'algorithme utilisé par les navigateurs eux-mêmes est trop compliqué à reproduire. Peut-être pouvez-vous restreindre vos exigences, par exemple "ne considérer que input , button y textarea et ignorent tabindex attribut".

0 votes

Nous avons besoin de voir votre .newElementByTabIndex parce que c'est ce qui ne fonctionne pas.

87voto

Je n'ai jamais mis en œuvre cette solution, mais je me suis penché sur un problème similaire, et voici ce que j'essaierais.

Essayez d'abord ceci

D'abord, je verrais si vous pouvez simplement tirer un keypress événement pour la touche Tab sur l'élément qui a actuellement le focus. Il peut y avoir une manière différente de procéder selon les navigateurs.

Si ça ne marche pas, vous devrez travailler plus dur

En faisant référence à l'implémentation de jQuery, vous devez :

  1. Écouter pour Tab et Shift+Tab
  2. Savoir quels éléments sont tabulables
  3. Comprendre le fonctionnement de l'ordre des onglets

1. Écoutez pour Tab et Shift+Tab

L'écoute de la touche Tab et de la touche Shift+Tab est probablement bien couverte ailleurs sur le web, je vais donc sauter cette partie.

2. Savoir quels éléments peuvent être tabulés

Il est plus difficile de savoir quels éléments peuvent être tabulés. Fondamentalement, un élément est tabulable s'il est focalisable et ne possède pas l'attribut tabindex="-1" ensemble. Il faut donc se demander quels éléments sont focalisables. Les éléments suivants sont focalisables :

  • input , select , textarea , button y object éléments qui ne sont pas désactivés.
  • a y area qui ont un href ou avoir une valeur numérique pour tabindex set.
  • tout élément qui a une valeur numérique pour tabindex set.

En outre, un élément est focalisable uniquement si :

  • Aucun de ses ancêtres n'est display: none .
  • La valeur calculée de visibility es visible . Cela signifie que l'ancêtre le plus proche d'avoir visibility doit avoir une valeur de visible . Si aucun ancêtre n'a visibility défini, alors la valeur calculée est visible .

Plus de détails dans une autre Réponse de Stack Overflow .

3. Comprendre le fonctionnement de l'ordre des onglets

L'ordre de tabulation des éléments dans un document est contrôlé par l'élément tabindex attribut. Si aucune valeur n'est définie, le tabindex est effectivement 0 .

El tabindex La commande du document est : 1, 2, 3, , 0.

Initialement, lorsque le body (ou aucun élément) a le focus, le premier élément dans l'ordre de tabulation est l'élément non nul le plus bas. tabindex . Si plusieurs éléments ont le même tabindex vous allez ensuite dans l'ordre des documents jusqu'à ce que vous atteigniez le dernier élément avec cet élément. tabindex . Ensuite, vous passez au niveau inférieur suivant tabindex et le processus continue. Enfin, terminez avec les éléments ayant un zéro (ou vide) tabindex .

1 votes

82 upvotes sans un seul commentaire à indiquer dont des solutions proposées fonctionne réellement ?

1 votes

Je me demande la même chose, mais je ne sais pas quelle solution est la bonne.

52voto

Max Points 892

Voici quelque chose que j'ai construit dans ce but :

focusNextElement: function () {
    //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();
        }                    
    }
}

Caractéristiques :

  • ensemble configurable d'éléments focalisables
  • pas besoin de jQuery
  • fonctionne dans tous les navigateurs modernes
  • rapide et léger

2 votes

C'est la solution la plus efficace et la plus respectueuse des ressources. Merci ! Voici mon script complet et fonctionnel : stackoverflow.com/a/40686327/1589669

0 votes

J'ai ajouté un snippet ci-dessous pour inclure le tri par TabIndex explicite focussable.sort(sort_by_TabIndex)

1 votes

Le meilleur ! Il doit être aussi complexe : le nextElementSibling peut ne pas être focalisable, le prochain focalisable peut ne pas être un frère ou une sœur.

29voto

Brian Glaz Points 5833

Sans jquery : Tout d'abord, sur vos éléments tabulables, ajoutez class="tabable" cela nous permettra de les sélectionner plus tard. (N'oubliez pas le préfixe du sélecteur de classe "." dans le code ci-dessous)

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;
        }
    }
}

25 votes

Une solution sans avoir à ajouter un nom à chaque élément (car il y en a beaucoup trop pour que ce soit faisable) serait idéale.

3 votes

Ok, c'est pour un formulaire ? Si tous les éléments que vous voulez sont des éléments de saisie, vous pouvez remplacer la ligne var tabbables = document.getElementsByName("tabable"); con var tabbables = document.getElementsByTagName("input"); au lieu de

1 votes

var tabbables = document.querySelectorAll("input, textarea, button") // IE8+ , obtenez une référence à tous les onglets sans modifier votre HTML.

26voto

Mark Lagendijk Points 1232

J'ai créé un plugin jQuery simple qui fait exactement cela. Il utilise le sélecteur ':tabbable' de jQuery UI pour trouver le prochain élément 'tabbable' et le sélectionner.

Exemple d'utilisation :

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

0 votes

C'est de loin la meilleure solution.

1 votes

Un petit aperçu pour ceux qui ne veulent pas installer un plug-in : var selectables = $(':focusable'); var currentIndex = selectables.index($(':focus')); selectables.eq(currentIndex + 1).focus(); Le plugin dispose d'une vérification des erreurs et de plus d'options.

9voto

Werlang Points 37

Le cœur de la réponse réside dans la recherche de l'élément suivant :

  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];
  }

Utilisation :

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

Remarquez que je ne me soucie pas d'établir des priorités. tabIndex .

3 votes

Que faire si l'ordre des tabindex va à l'encontre de l'ordre des documents ? Je pense que le tableau doit être trié par numéro de tabindex puis par ordre de document.

0 votes

Oui, ce serait plus "conforme aux spécifications". Je ne suis pas sûr des cas limites, concernant les éléments parents, etc.

0 votes

Et si un élément qui n'est pas l'une de ces balises possède un attribut tabindex ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X