Amélioration de l'UX avec la touche Tab

Lors du développement d'applications, les fournisseurs frontaux font rarement attention à la façon dont l'utilisateur utilisera les fonctions du clavier fournies par le navigateur. Je ne fais pas exception, mais un jour on m'a confié une tâche concernant l'UX et les transitions en appuyant sur «Tab» et «Shift + Tab».

L'essence de la tâche est transparente et propre: il existe une interface dont la disposition est affichée ci-dessous. Sur le plan conceptuel, une page peut contenir 2 formulaires différents et l'exigence était que «l'exécution avec des onglets ne passe pas d'un formulaire à un autre».

image

Tout irait bien si le navigateur savait comment bloquer "nativement" le focus dans les formulaires. Un exemple est présenté dans la figure ci-dessous, où la bordure orange indique l'élément actuel et le précédent est gris.

image

Comme vous pouvez le voir, le comportement "natif" ne répond pas aux exigences. Alors, résolvons ce problème. La solution n'est pas compliquée, alors pensez-y.

Il serait idéal s'il y avait des «portes» qui empêcheraient de «sauter» de la focalisation du dernier (avec «Tab») ou du premier (avec «Shift + Tab») élément avec «tabindex» ou prenant en charge la focalisation par défaut. Donc, l'essence est simple: nos «portes» sont des «éléments d'entrée» cachés, qui reçoivent un événement «événement» comme argument pendant l'événement «onFocus» et retournent le focus à l'élément dont il est issu. Illustration ci-dessous.

image

L'obtention de l'élément précédent est possible en utilisant la propriété "relatedTarget" de l'objet "event". Visualisation de la solution ci-dessous.

image

Et voici le code lui-même. Il convient de noter qu'il n'y a pas de syntaxe "ES6 +", car l'idée de prendre en charge le code avec différents navigateurs sans connecter différents "transpilers" comme Babel est au cœur.

function getGateInput(handleTabOut) { var input = document.createElement("input"); // not visibiliy:hidden or display:none as need to focus on this element var hiddingStyle = "opacity: 0;cursor: none;position: absolute;top: -10px;left: -10px;"; input.setAttribute("style", hiddingStyle); input.addEventListener("focus", handleTabOut); return input; } 

Il n'y a rien de compliqué: une «entrée» est créée, des styles sont définis qui «cachent» nos «portes». Ici, «afficher: aucun» n'est pas utilisé, car le navigateur ne concentre pas les «onglets» sur de tels éléments. En raison de ce comportement, il est nécessaire de rendre l'élément transparent et de le déplacer hors de la fenêtre du navigateur.

 function getTabOutHandler(element, GATES) { return function(event) { var relatedTarget = event.relatedTarget || event.fromElement; var target = event.target; var gatesTrapped = target === GATES[0] || target === GATES[1]; if (gatesTrapped && isChild(relatedTarget, element)) { event.preventDefault(); relatedTarget.focus(); } }; } 

Pour retourner le focus à l'élément précédent, utilisez getTabOutHandler. C'est le HOC . Son premier argument est notre conteneur (celui autour duquel nous avons défini la «porte»), et le second, il attend un tableau de «portes» que nous avons créé à l'aide de getGateInput. Cette fonction renvoie un gestionnaire d'événements qui fonctionne selon le principe décrit ci-dessus.

Pour que le focus rentre dans le conteneur, nous devons ouvrir et fermer la «porte». Nous allons le faire en définissant l'attribut «tabindex» . (-1 - ne pas se concentrer avec les onglets, 0 - se concentrer en fonction du flux)

 function moveGates(open, GATES) { GATES[0].setAttribute("tabindex", open ? -1 : 0); GATES[1].setAttribute("tabindex", open ? -1 : 0); } 

Pour contrôler les portes, nous allons mettre en place un gestionnaire qui "écoutera" en appuyant sur Tab (code 9) et si l'élément focalisé (activeElement) est à l'intérieur du conteneur, puis fermons la "porte", sinon l'ouvrir.

 window.addEventListener("keydown", function(event) { if (event.keyCode === 9) { if (isChild(document.activeElement, element)) { moveGates(false, GATES); } else { moveGates(true, GATES); } } }); 

Total


Une méthode de verrouillage du focus dans un formulaire a été envisagée, qui consiste à retourner le focus à un élément focalisé précédent. Pour "attraper" le focus, nous avons utilisé des "éléments d'entrée" cachés, dont le focus était contrôlé à l'aide du "tabindex" . Le code ci-dessus fait partie de la bibliothèque tab-out-catcher que j'ai écrite pour résoudre mon problème. Des exemples d'utilisation peuvent être trouvés ici . Il existe également une solution pour les applications React.

Source: https://habr.com/ru/post/fr469749/


All Articles