2017-03-27 1 views
0

contexte rapide:
J'ai une liste des zones de texte, et pour chacun d'eux, l'utilisateur entre un numéro, puis sur le flou de cette zone de texte (l'utilisateur clique sur TAB), si le nombre répond à certains critères, une liste déroulante cachée est affichée à côté de celle-ci, puis est mise en évidence.Impossible de définir la mise au point sur une entrée lorsque document.activeElement est le corps (ou nul)

Problème:
Lorsque l'utilisateur atteint la dernière zone de texte et frappe onglet, car le menu déroulant est caché à ce moment-là, l'utilisateur a atteint le dernier élément en mesure mise au point, et donc l'élément actif devient le corps ou null (pour plus d'informations, voir Mozilla's documentation on document.activeElement). Le problème est - une fois que cela arrive, appeler focus() sur n'importe quel élément de la page ne fait rien.

Exemple:
Here's a codepen I created où vous pouvez voir ce comportement. Après avoir ouvert ce lien codepen (de préférence dans Chrome), ouvrez votre console d'outils de développement. Cliquez sur la 2ème zone de texte (au milieu), puis appuyez sur TAB. Regardez votre console - après 1 seconde, l'élément actif actuel sera enregistré (vous pouvez voir qu'il dira # input-3), et la console dira "se préparer à se concentrer sur # input-1" ... ", puis 2 secondes plus tard, le code essayera de mettre l'accent sur la première zone de texte (# entrée-1), mais si vous cliquez sur la dernière zone de texte, vous obtiendrez TAB, il va dire que l'élément actif est le corps, puis il va essayer de se concentrer sur # entrée-1, mais rien ne se passera

Alors, quel est le problème, et comment puis-je par programme mettre l'accent sur un élément lorsque document.activeElement est le corps ou null?

Répondre

1

Cela dépend s'il y a une raison pour laquelle le focus aurait à un quittez l'élément. Votre codepen utilise l'événement keydown, qui est déclenché avant que le flou ne se produise. Ceci est assez tôt pour empêcher le changement de mise au point avec event.preventDefault() (synchronuously, sans délai d'attente!):

$('input').on('keydown', function(event) { 
    if(/* is this a keypress that would change focus? */ && 
     /* are criteria fullfilled? */) { 
      event.preventDefault(); 
      $(/* target element */).focus(); 
    } 
)} 

C'est un peu alambiquée, et si vous ne se soucient pas de la compatibilité Firefox, pourrait être écrit à l'événement focusout , ce qui déclenche avant focus quitte l'élément:

$('input').on('focusout', function(event) { 
    if(/* are criteria fullfilled? */) { 
      $(/* target element */).focus(); 
    } 
)} 

Soit dit en passant, l'événement a focusout finalement atterri dans la dernière version de Firefox (52): http://caniuse.com/#search=focusout