1613 votes

Comment puis-je savoir quel élément du DOM a le focus ?

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'ai besoin. Existe-t-il un moyen de le faire, et comment ?

La raison pour laquelle je cherchais ça :

J'essaye de faire en sorte que les touches comme les flèches et les enter naviguer dans un tableau d'éléments d'entrée. La tabulation fonctionne maintenant, mais l'entrée et les flèches ne fonctionnent pas par défaut, semble-t-il. J'ai mis en place la partie de gestion des touches, mais je dois maintenant trouver comment déplacer le focus dans les fonctions de gestion des événements.

4 votes

Voici un bookmarklet qui console.log l'élément avec focus : github.com/lingtalfi/where-is-focus-bookmarklet

1 votes

Vous pouvez utiliser find-focused-element paquet : npmjs.com/package/find-focused-element

1 votes

Pour moi, le bookmarklet que Ling a mentionné ne fonctionne pas.

1897voto

JW. Points 17361

Utilice document.activeElement il est pris en charge par tous les principaux navigateurs.

Auparavant, si vous essayiez de savoir quel champ de formulaire avait le focus, vous ne pouviez pas le faire. Pour émuler la détection dans les anciens navigateurs, ajoutez un gestionnaire d'événement "focus" à tous les champs et enregistrez le dernier champ ciblé dans une variable. Ajoutez un gestionnaire d'événement "blur" pour effacer la variable en cas d'événement blur pour le dernier champ ciblé.

Si vous devez retirer le activeElement vous pouvez utiliser le flou ; document.activeElement.blur() . Il changera le activeElement a body .

Liens connexes :

2 votes

Si aucun élément n'a été mis au point, que renvoie document.activeElement ? Peut-on s'attendre à ce qu'il soit cohérent entre les navigateurs qui le supportent ?

69 votes

Je ne suis pas sûr pour IE, mais FF et Safari renvoient tous deux l'élément BODY.

1 votes

Avons-nous accès à la connaissance de l'élément qui a été mis au point précédemment ?

157voto

Wookai Points 8647

Comme l'a dit JW, vous ne pouvez pas trouver l'élément actuellement ciblé, du moins d'une manière indépendante du navigateur. Mais si votre application est uniquement IE (certaines le sont...), vous pouvez le trouver de la manière suivante :

document.activeElement

Il semble qu'IE n'avait pas tout faux après tout, cela fait partie du projet HTML5 et semble être pris en charge par la dernière version de Chrome, Safari et Firefox au moins.

5 votes

FF3 aussi. Cela fait en fait partie de la spécification HTML5 concernant la "gestion de la mise au point".

2 votes

Il fonctionne dans la version actuelle de Chrome et d'Opera (9.62). Il ne fonctionne pas dans Safari 3.2.3 sur OS X, mais il fonctionne dans Safari 4 qui est sorti hier :)

0 votes

Toujours la même chose pour le chrome 19 :S

96voto

William Denniss Points 3781

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 permettra d'obtenir l'élément actuellement ciblé.

$(":focus")

De : Comment sélectionner un élément qui a le focus sur lui avec jQuery ?

6 votes

C'est bien, mais comment jQuery fait-il ? document.activeElement ? J'ai trouvé ceci : return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);

52voto

Andy E Points 132925

document.activeElement est maintenant fait partie du projet de travail HTML5 mais il se peut qu'elle ne soit pas encore prise en charge par certains navigateurs non majeurs/mobiles/anciens. Vous pouvez vous rabattre sur querySelector (si cela est possible). Il convient également de mentionner que document.activeElement retournera document.body si aucun élément n'est focalisé - même si la fenêtre du navigateur n'a pas le focus.

Le code suivant permet de contourner ce problème et de revenir à l'option querySelector donnant un peu plus de soutien.

var focused = document.activeElement;
if (!focused || focused == document.body)
    focused = null;
else if (document.querySelector)
    focused = document.querySelector(":focus");

Il convient également de noter 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 au fichier activeElement propriété. Voir ce test jsperf.com .

12voto

Jason Points 208

J'ai aimé l'approche utilisée par Joel S, mais j'aime également la simplicité de document.activeElement . J'ai utilisé jQuery et combiné les deux. Les anciens navigateurs qui ne supportent pas document.activeElement utilisera jQuery.data() pour stocker la valeur de "hasFocus". Les navigateurs plus récents utiliseront document.activeElement . Je suppose que document.activeElement aura de meilleures performances.

(function($) {
var settings;
$.fn.focusTracker = function(options) {
    settings = $.extend({}, $.focusTracker.defaults, options);

    if (!document.activeElement) {
        this.each(function() {
            var $this = $(this).data('hasFocus', false);

            $this.focus(function(event) {
                $this.data('hasFocus', true);
            });
            $this.blur(function(event) {
                $this.data('hasFocus', false);
            });
        });
    }
    return this;
};

$.fn.hasFocus = function() {
    if (this.length === 0) { return false; }
    if (document.activeElement) {
        return this.get(0) === document.activeElement;
    }
    return this.data('hasFocus');
};

$.focusTracker = {
    defaults: {
        context: 'body'
    },
    focusedElement: function(context) {
        var focused;
        if (!context) { context = settings.context; }
        if (document.activeElement) {
            if ($(document.activeElement).closest(context).length > 0) {
                focused = document.activeElement;
            }
        } else {
            $(':visible:enabled', context).each(function() {
                if ($(this).data('hasFocus')) {
                    focused = this;
                    return false;
                }
            });
        }
        return $(focused);
    }
};
})(jQuery);

3 votes

Pourrait-elle être remplacée par celle de @William Denniss ? $("*:focus") ?

0 votes

Je suppose que c'est possible. J'ai écrit ceci il y a longtemps et je n'ai jamais eu de raison de revenir sur une meilleure solution, maintenant que c'est 5 ans plus tard. Essayez-le ! Je pourrais faire la même chose. Un plugin de moins sur notre site ! :)

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