Je voudrais savoir, en JavaScript, quel élément a actuellement le focus. J'ai parcouru le DOM et je n'ai pas encore trouvé ce dont j'avais besoin. Y a-t-il un moyen de le faire et comment?
La raison pour laquelle je cherchais ceci:
J'essaie de créer des touches comme les flèches et de enter
parcourir une table d'éléments d'entrée. Tab fonctionne maintenant, mais entrez, et les flèches ne le semblent pas par défaut. J'ai mis en place la partie de gestion des clés, mais maintenant je dois comprendre comment déplacer le focus dans les fonctions de gestion des événements.
javascript
dom
Tony Peterson
la source
la source
find-focused-element
package: npmjs.com/package/find-focused-elementRéponses:
Utilisez
document.activeElement
, il est pris en charge dans tous les principaux navigateurs.Auparavant, si vous essayiez de savoir quel champ de formulaire était ciblé, vous ne pouviez pas. Pour émuler la détection dans des navigateurs plus anciens, ajoutez un gestionnaire d'événements "focus" à tous les champs et enregistrez le dernier champ focalisé dans une variable. Ajoutez un gestionnaire de "flou" pour effacer la variable lors d'un événement de flou pour le dernier champ focalisé.
Si vous devez supprimer le,
activeElement
vous pouvez utiliser le flou;document.activeElement.blur()
. Il va changeractiveElement
àbody
.Liens connexes:
la source
activeElement
ne renvoie en fait pas l'élément focalisé. Tout élément peut avoir le focus. Si un document a 4 'divisions de défilement', 0 ou 1 de ces divisions peut défiler avec les touches fléchées. Si vous cliquez sur un, ce div est focalisé. Si vous cliquez en dehors de tout, le corps est concentré. Comment savoir sur quel scrolldiv se concentre? jsfiddle.net/rudiedirkx/bC5ke/show (vérifier la console)div
navigateur est Firefox 17, et uniquement en le tabulant . Les types d'éléments renvoyés par TOUS les principaux navigateursdocument.activeElement
sont limités aux éléments liés à l' entrée . Si aucun élément de ce type n'a le focus, tous les principaux navigateurs renvoient l'body
élément - à l'exception d'IE 9, qui renvoie l'html
élément.document.activeElement
doit être encapsulétry catch
car dans certaines circonstances, il peut lever une exception (pas seulement IE9 AFAIK). Voir bugs.jquery.com/ticket/13393 et bugs.jqueryui.com/ticket/8443Comme l'a dit JW, vous ne pouvez pas trouver l'élément ciblé actuel, au moins d'une manière indépendante du navigateur. Mais si votre application est uniquement IE (certains le sont ...), vous pouvez la trouver de la manière suivante:
EDIT: Il semble qu'IE n'ait pas tout mal après tout, cela fait partie du brouillon HTML5 et semble être pris en charge par la dernière version de Chrome, Safari et Firefox au moins.
la source
Si vous pouvez utiliser jQuery, il prend désormais en charge: focus, assurez-vous simplement que vous utilisez la version 1.6+.
Cette déclaration vous donnera l'élément actuellement ciblé.
De: Comment sélectionner un élément qui se concentre dessus avec jQuery
la source
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
document.activeElement
fait maintenant partie de la spécification de brouillon HTML5 , mais elle n'est peut-être pas encore prise en charge dans certains navigateurs non majeurs / mobiles / plus anciens. Vous pouvez revenir àquerySelector
(si cela est pris en charge). Il convient également de mentionner quedocument.activeElement
cela reviendradocument.body
si aucun élément n'est focalisé - même si la fenêtre du navigateur n'a pas le focus.Le code suivant contournera ce problème et se rabattra sur
querySelector
un meilleur support.Une autre chose à noter est la différence de performances entre ces deux méthodes. L'interrogation du document avec des sélecteurs sera toujours beaucoup plus lente que l'accès à la
activeElement
propriété. Voir ce test jsperf.com .la source
En soi,
document.activeElement
peut toujours renvoyer un élément si le document n'est pas focalisé (et donc rien dans le document n'est focalisé!)Vous voudrez peut -être ce comportement, ou il peut ne pas avoir d'importance (par exemple dans un
keydown
événement), mais si vous avez besoin de savoir que quelque chose est réellement concentré, vous pouvez également vérifierdocument.hasFocus()
.Ce qui suit vous donnera l'élément focalisé s'il y en a un, ou bien
null
.Pour vérifier si un élément spécifique a le focus, c'est plus simple:
Pour vérifier si quelque chose est ciblé, c'est encore plus complexe:
Remarque sur la robustesse : dans le code dans lequel il vérifie
document.body
etdocument.documentElement
, c'est parce que certains navigateurs retournent l'un d'eux ounull
lorsque rien n'est focalisé.Il ne prend pas en compte si le
<body>
(ou peut-être<html>
) avait untabIndex
attribut et pouvait donc être réellement concentré . Si vous écrivez une bibliothèque ou quelque chose et que vous voulez qu'elle soit robuste, vous devriez probablement gérer cela d'une manière ou d'une autre.Voici une version ( one-liner) ( lourd airquotes) pour obtenir l'élément focalisé, ce qui est conceptuellement plus compliqué parce que vous devez connaître les courts-circuits, et vous savez, cela ne tient évidemment pas sur une seule ligne, en supposant que vous veulent qu'il soit lisible.
Je ne recommanderai pas celui-ci. Mais si vous êtes un 1337 hax0r, idk ... il est là.
Vous pouvez également retirer la
|| null
pièce si cela ne vous dérange pas d'obtenirfalse
dans certains cas. (Vous pouvez toujours obtenirnull
sidocument.activeElement
estnull
):Pour vérifier si un élément spécifique est ciblé, vous pouvez également utiliser des événements, mais cette méthode nécessite une configuration (et éventuellement un démontage) et, surtout, suppose un état initial :
Vous pouvez corriger l'hypothèse de l'état initial en utilisant la méthode sans événement, mais vous pourriez aussi bien l'utiliser à la place.
la source
document.activeElement
peut par défaut être l'<body>
élément si aucun élément focalisable n'est au point. De plus, si un élément est mis au point et que la fenêtre du navigateur est floue,activeElement
il continuera de contenir l'élément mis au point.Si l' une de ces deux comportements ne sont pas souhaitables, envisager une approche basée sur CSS:
document.querySelector( ':focus' )
.la source
querySelector
: stackoverflow.com/a/40873560/2624876J'ai aimé l'approche utilisée par Joel S, mais j'aime aussi la simplicité de
document.activeElement
. J'ai utilisé jQuery et combiné les deux. Les navigateurs plus anciens qui ne prennent pas en chargedocument.activeElement
utiliserontjQuery.data()
pour stocker la valeur de «hasFocus». Les nouveaux navigateurs utiliserontdocument.activeElement
. Je suppose quedocument.activeElement
cela aura de meilleures performances.la source
$("*:focus")
?Un petit assistant que j'ai utilisé à ces fins dans Mootools:
De cette façon, vous pouvez vérifier si l'élément a le focus à
el.hasFocus()
condition d'startFocusTracking()
avoir été appelé sur l'élément donné.la source
JQuery prend en charge la
:focus
pseudo-classe en cours. Si vous le recherchez dans la documentation JQuery, vérifiez sous "Sélecteurs" où il vous pointe vers les documents CSS du W3C . J'ai testé avec Chrome, FF et IE 7+. Notez que pour qu'il fonctionne dans IE, il<!DOCTYPE...
doit exister sur la page html. Voici un exemple en supposant que vous avez attribué un identifiant à l'élément qui a le focus:la source
this.id
place de$(this).attr('id')
, ou du moins (lorsque vous avez déjà votre objet jQuery)$(this)[0].id
. Javascript natif à ce niveau est bien plus rapide et plus efficace. Cela pourrait ne pas être visible dans ce cas, mais à l'échelle du système, vous remarquerez une différence.Si vous voulez obtenir un objet qui est une instance de
Element
, vous devez utiliserdocument.activeElement
, mais si vous voulez obtenir un objet qui est une instance deText
, vous devez utiliserdocument.getSelection().focusNode
.J'espère que ça aide.
la source
document.getSelection().focusNode.parentElement
et appuyez sur Entrée. Après cela, passezdocument.activeElement
et faites-le. ;)document.activeElement
donne le<textarea>
alorsdocument.getSelection().focusNode
donne le<td>
qui contient le<textarea>
(etdocument.getSelection().focusNode.parentElement
donne le<tr>
contenant le<td>
)Element
, vous devez utiliserdocument.activeElement
, mais si vous voulez obtenir un objet qui est une instance deText
, vous devez utiliserdocument.getSelection().focusNode
. Veuillez le tester à nouveau. J'espère avoir aidé.focusNode
n'est pas non plus garanti d'être un nœud de texte.Il existe des problèmes potentiels avec l'utilisation de document.activeElement. Considérer:
Si l'utilisateur se concentre sur un div interne, document.activeElement fait toujours référence au div externe. Vous ne pouvez pas utiliser document.activeElement pour déterminer lequel des div internes a le focus.
La fonction suivante contourne cela et renvoie le nœud focalisé:
Si vous préférez obtenir l'élément ciblé, utilisez:
la source
document.activeElement
: les<div>
éléments internes ne peuvent pas réellement recevoir le focus, comme vous pouvez le voir visuellement en définissant la:focus
pseudo-classe sur quelque chose de visible (exemple: jsfiddle.net/4gasa1t2/1 ). Ce dont vous parlez, c'est lequel des intérieurs<div>
contient la sélection ou le curseur, qui est un problème distinct.J'ai trouvé l'extrait de code suivant utile pour essayer de déterminer quel élément a actuellement le focus. Copiez ce qui suit dans la console de votre navigateur, et chaque seconde il imprimera les détails de l'élément courant qui a le focus.
N'hésitez pas à modifier le
console.log
pour vous déconnecter de quelque chose de différent afin de vous aider à localiser l'élément exact si l'impression de l'élément entier ne vous aide pas à localiser l'élément.la source
En lisant d'autres réponses et en essayant moi-même, cela
document.activeElement
vous donnera l'élément dont vous avez besoin dans la plupart des navigateurs.Si vous avez un navigateur qui ne prend pas en charge document.activeElement si vous avez jQuery autour, vous devriez pouvoir le remplir sur tous les événements de focus avec quelque chose de très simple comme ceci (non testé car je n'ai pas de navigateur répondant à ces critères à portée de main ):
la source
Si vous utilisez jQuery, vous pouvez l'utiliser pour savoir si un élément est actif:
la source
Avec dojo, vous pouvez utiliser dijit.getFocus ()
la source
Je mets juste cela ici pour donner la solution que j'ai finalement trouvée.
J'ai créé une propriété appelée document.activeInputArea, et utilisé l'addon HotKeys de jQuery pour intercepter les événements de clavier pour les touches fléchées, tabulation et entrée, et j'ai créé un gestionnaire d'événements pour cliquer sur les éléments d'entrée.
Ensuite, j'ai ajusté activeInputArea chaque fois que le focus changeait, afin que je puisse utiliser cette propriété pour savoir où j'étais.
Cependant, il est facile de gâcher cela, car si vous avez un bogue dans le système et que la mise au point n'est pas là où vous pensez, il est très difficile de restaurer la mise au point correcte.
la source